<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thiago da Silva Adriano</title>
    <description>The latest articles on DEV Community by Thiago da Silva Adriano (@programadriano).</description>
    <link>https://dev.to/programadriano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F66751%2F443a8dc4-b59b-43ba-bf34-137d0a91851f.jpeg</url>
      <title>DEV Community: Thiago da Silva Adriano</title>
      <link>https://dev.to/programadriano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/programadriano"/>
    <language>en</language>
    <item>
      <title>Apache Zookeeper: O coordenador de sistemas distribuídos</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Sun, 28 Sep 2025 14:36:48 +0000</pubDate>
      <link>https://dev.to/programadriano/apache-zookeeper-o-coordenador-de-sistemas-distribuidos-4d2a</link>
      <guid>https://dev.to/programadriano/apache-zookeeper-o-coordenador-de-sistemas-distribuidos-4d2a</guid>
      <description>&lt;p&gt;Apache Zookeeper é um serviço centralizado para manter informações de configuração, nomenclatura, sincronização distribuída e serviços de grupo em sistemas distribuídos. Desenvolvido originalmente pelo Yahoo!, tornou-se um projeto Apache de alto nível e é amplamente usado em ecossistemas de big data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Características principais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coordenação distribuída&lt;/strong&gt;: sincronização entre múltiplos nós&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência forte&lt;/strong&gt;: garantias ACID para operações críticas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alta disponibilidade&lt;/strong&gt;: tolerância a falhas com replicação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: baixa latência para operações de leitura&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicidade&lt;/strong&gt;: API simples baseada em sistema de arquivos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O problema que o Zookeeper resolve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Desafios de sistemas distribuídos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problema da eleição de líder:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cenário: 3 brokers Kafka precisam eleger um líder para uma partição
Sem Zookeeper: Como garantir que apenas um seja eleito?
Com Zookeeper: Algoritmo de consenso garante eleição única e consistente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problema da configuração distribuída:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cenário: 10 serviços precisam da mesma configuração atualizada
Sem Zookeeper: Cada serviço mantém sua própria cópia (inconsistência)
Com Zookeeper: Configuração centralizada com notificações automáticas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problema da descoberta de serviços:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cenário: Microserviços precisam encontrar uns aos outros
Sem Zookeeper: IPs hardcoded ou DNS complexo
Com Zookeeper: Registro dinâmico com health checks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Antes do Zookeeper: soluções inadequadas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Arquivos de configuração estáticos:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# broker1.properties&lt;/span&gt;
broker.id&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;listeners&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PLAINTEXT://192.168.1.10:9092

&lt;span class="c"&gt;# broker2.properties  &lt;/span&gt;
broker.id&lt;span class="o"&gt;=&lt;/span&gt;2
&lt;span class="nv"&gt;listeners&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PLAINTEXT://192.168.1.11:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problemas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configuração manual&lt;/strong&gt;: alterações exigem restart de serviços&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inconsistência&lt;/strong&gt;: diferentes versões de configuração&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falta de coordenação&lt;/strong&gt;: sem sincronização entre nós&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detecção de falhas&lt;/strong&gt;: sem mecanismo automático&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bancos de dados relacionais:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;cluster_config&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problemas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single point of failure&lt;/strong&gt;: banco centralizado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latência&lt;/strong&gt;: queries SQL para cada operação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexidade&lt;/strong&gt;: transações distribuídas complexas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt;: limitada pela capacidade do banco&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Como o Zookeeper funciona
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Modelo de dados hierárquico
&lt;/h3&gt;

&lt;p&gt;O Zookeeper organiza dados em uma estrutura de árvore similar a um sistema de arquivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
├── kafka/
│   ├── brokers/
│   │   ├── ids/
│   │   │   ├── 1 → {"host":"kafka1","port":9092}
│   │   │   ├── 2 → {"host":"kafka2","port":9092}
│   │   │   └── 3 → {"host":"kafka3","port":9092}
│   │   └── topics/
│   │       └── ecommerce.produtos/
│   │           └── partitions/
│   │               ├── 0 → {"leader":1,"replicas":[1,2]}
│   │               └── 1 → {"leader":2,"replicas":[2,3]}
│   ├── controller/
│   │   └── epoch → {"brokerid":1,"epoch":15}
│   └── config/
│       └── topics/
│           └── ecommerce.produtos → {"retention.ms":604800000}
└── debezium/
    └── connectors/
        └── ecommerce-connector/
            ├── status → "RUNNING"
            └── config → {"database.hostname":"sqlserver"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tipos de nós (znodes)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nós persistentes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permanecem até serem explicitamente deletados&lt;/li&gt;
&lt;li&gt;Usados para configurações e metadados&lt;/li&gt;
&lt;li&gt;Exemplo: &lt;code&gt;/kafka/config/topics/meu-topico&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Nós efêmeros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deletados automaticamente quando a sessão termina&lt;/li&gt;
&lt;li&gt;Usados para detecção de falhas e presença&lt;/li&gt;
&lt;li&gt;Exemplo: &lt;code&gt;/kafka/brokers/ids/1&lt;/code&gt; (broker ativo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Nós sequenciais:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recebem sufixo numérico automático&lt;/li&gt;
&lt;li&gt;Usados para eleição de líder e filas&lt;/li&gt;
&lt;li&gt;Exemplo: &lt;code&gt;/kafka/controller/election/n_0000000001&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Algoritmo de consenso
&lt;/h3&gt;

&lt;p&gt;Zookeeper usa uma variação do algoritmo &lt;strong&gt;Zab (Zookeeper Atomic Broadcast)&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fase de eleição&lt;/strong&gt;: nós elegem um líder&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase de descoberta&lt;/strong&gt;: líder coleta estado dos seguidores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase de sincronização&lt;/strong&gt;: líder sincroniza todos os nós&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fase de broadcast&lt;/strong&gt;: líder processa escritas e replica
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Líder (Zookeeper 1)     Seguidor (Zookeeper 2)    Seguidor (Zookeeper 3)
       |                        |                         |
   1. Proposta ----------------&amp;gt; |                         |
       |                   2. ACK                         |
       |                        |                         |
   3. Proposta ---------------------------------&amp;gt; |
       |                        |            4. ACK
   5. Commit -----------------&amp;gt; |                         |
   6. Commit ---------------------------------&amp;gt; |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Papel do Zookeeper no ecossistema Kafka
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gerenciamento de brokers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Registro de brokers:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/kafka/brokers/ids/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kafka-broker-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9092&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jmx_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1640995200000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"endpoints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PLAINTEXT://kafka-broker-1:9092"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rack1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Detecção de falhas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brokers mantêm sessões efêmeras com Zookeeper&lt;/li&gt;
&lt;li&gt;Se broker falha, nó efêmero é removido automaticamente&lt;/li&gt;
&lt;li&gt;Outros brokers são notificados da mudança&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Eleição de controller
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Kafka Controller&lt;/strong&gt; é o broker responsável por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gerenciar partições e réplicas&lt;/li&gt;
&lt;li&gt;Coordenar eleições de líder de partição&lt;/li&gt;
&lt;li&gt;Processar mudanças de metadados&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Processo de eleição:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Broker 1 tenta criar /kafka/controller (nó efêmero)
2. Se sucesso → Broker 1 vira controller
3. Se falha → outro broker já é controller
4. Todos os brokers assistem /kafka/controller para mudanças
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Metadados de tópicos e partições
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Configuração de tópico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/kafka/config/topics/ecommerce-produtos&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retention.ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"604800000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cleanup.policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compression.type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"snappy"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Estado de partições:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/kafka/brokers/topics/ecommerce-produtos&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"partitions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;broker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;líder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;são&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;réplicas&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;broker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;líder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;são&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;réplicas&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;broker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;líder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;são&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;réplicas&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Arquitetura e componentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ensemble Zookeeper
&lt;/h3&gt;

&lt;p&gt;Um &lt;strong&gt;ensemble&lt;/strong&gt; é um cluster de servidores Zookeeper que trabalham juntos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cliente 1 ──┐
Cliente 2 ──┼─── Zookeeper 1 (Líder)
Cliente 3 ──┘         │
                       │ Replicação
                       ├─── Zookeeper 2 (Seguidor)
                       │
                       └─── Zookeeper 3 (Seguidor)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Características do ensemble:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Número ímpar&lt;/strong&gt;: 3, 5, 7 nós (evita split-brain)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quorum&lt;/strong&gt;: maioria deve estar ativa (2/3, 3/5, 4/7)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Líder único&lt;/strong&gt;: processa todas as escritas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seguidores&lt;/strong&gt;: processam leituras e replicam escritas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sessões e watches
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sessões:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conexão entre cliente e ensemble&lt;/li&gt;
&lt;li&gt;Timeout configurável (heartbeat)&lt;/li&gt;
&lt;li&gt;Estado mantido enquanto sessão ativa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Watches (observadores):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cliente Java registra watch&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/kafka/brokers/ids/1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Watcher&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WatchedEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NodeDeleted&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Broker 1 falhou!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tipos de eventos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NodeCreated&lt;/code&gt;: nó foi criado&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NodeDeleted&lt;/code&gt;: nó foi removido
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NodeDataChanged&lt;/code&gt;: dados do nó mudaram&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NodeChildrenChanged&lt;/code&gt;: filhos do nó mudaram&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuração e deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuração básica
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;zoo.cfg:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identificação do servidor
&lt;/span&gt;&lt;span class="py"&gt;tickTime&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2000&lt;/span&gt;
&lt;span class="py"&gt;initLimit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="py"&gt;syncLimit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5&lt;/span&gt;

&lt;span class="c"&gt;# Diretório de dados
&lt;/span&gt;&lt;span class="py"&gt;dataDir&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/zookeeper&lt;/span&gt;

&lt;span class="c"&gt;# Porta para clientes
&lt;/span&gt;&lt;span class="py"&gt;clientPort&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2181&lt;/span&gt;

&lt;span class="c"&gt;# Configuração do ensemble
&lt;/span&gt;&lt;span class="py"&gt;server.1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zk1:2888:3888&lt;/span&gt;
&lt;span class="py"&gt;server.2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zk2:2888:3888  &lt;/span&gt;
&lt;span class="py"&gt;server.3&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;zk3:2888:3888&lt;/span&gt;

&lt;span class="c"&gt;# Configurações de performance
&lt;/span&gt;&lt;span class="py"&gt;maxClientCnxns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;60&lt;/span&gt;
&lt;span class="py"&gt;autopurge.snapRetainCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;autopurge.purgeInterval&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicação dos parâmetros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tickTime&lt;/code&gt;: unidade básica de tempo (ms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;initLimit&lt;/code&gt;: tempo para seguidores se conectarem ao líder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;syncLimit&lt;/code&gt;: tempo para seguidores sincronizarem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2888&lt;/code&gt;: porta para comunicação entre servidores&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3888&lt;/code&gt;: porta para eleição de líder&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuração para produção
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Otimizações de performance:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Aumentar heap JVM
&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt; &lt;span class="py"&gt;JVMFLAGS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"-Xmx4G -Xms4G"&lt;/span&gt;

&lt;span class="c"&gt;# Configurações de rede
&lt;/span&gt;&lt;span class="py"&gt;maxClientCnxns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;
&lt;span class="py"&gt;minSessionTimeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;4000&lt;/span&gt;
&lt;span class="py"&gt;maxSessionTimeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;40000&lt;/span&gt;

&lt;span class="c"&gt;# Configurações de disco
&lt;/span&gt;&lt;span class="py"&gt;preAllocSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;65536&lt;/span&gt;
&lt;span class="py"&gt;snapCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;100000&lt;/span&gt;

&lt;span class="c"&gt;# Configurações de log
&lt;/span&gt;&lt;span class="py"&gt;zookeeper.log.threshold&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;INFO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Monitoramento:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Habilitar métricas JMX
&lt;/span&gt;&lt;span class="py"&gt;com.sun.management.jmxremote&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;com.sun.management.jmxremote.port&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;9999&lt;/span&gt;
&lt;span class="py"&gt;com.sun.management.jmxremote.authenticate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;com.sun.management.jmxremote.ssl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Operações e comandos essenciais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cliente de linha de comando
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Conectar ao Zookeeper:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conectar ao ensemble&lt;/span&gt;
zkCli.sh &lt;span class="nt"&gt;-server&lt;/span&gt; zk1:2181,zk2:2181,zk3:2181
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Comandos básicos:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Listar nós filhos&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; /kafka/brokers/ids

&lt;span class="c"&gt;# Obter dados de um nó&lt;/span&gt;
get /kafka/controller

&lt;span class="c"&gt;# Criar nó&lt;/span&gt;
create /teste &lt;span class="s2"&gt;"dados do teste"&lt;/span&gt;

&lt;span class="c"&gt;# Atualizar nó&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; /teste &lt;span class="s2"&gt;"novos dados"&lt;/span&gt;

&lt;span class="c"&gt;# Deletar nó&lt;/span&gt;
delete /teste

&lt;span class="c"&gt;# Estatísticas do nó&lt;/span&gt;
&lt;span class="nb"&gt;stat&lt;/span&gt; /kafka/brokers/ids/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comandos administrativos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Status do ensemble:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar status de cada servidor&lt;/span&gt;
&lt;span class="nb"&gt;echo stat&lt;/span&gt; | nc zk1 2181
&lt;span class="nb"&gt;echo stat&lt;/span&gt; | nc zk2 2181  
&lt;span class="nb"&gt;echo stat&lt;/span&gt; | nc zk3 2181

&lt;span class="c"&gt;# Verificar líder&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;srvr | nc zk1 2181 | &lt;span class="nb"&gt;grep &lt;/span&gt;Mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Limpeza de dados:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Limpar snapshots antigos&lt;/span&gt;
zkCleanup.sh &lt;span class="nt"&gt;-n&lt;/span&gt; 3

&lt;span class="c"&gt;# Verificar integridade&lt;/span&gt;
zkServer.sh status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Monitoramento e observabilidade
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Métricas importantes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Métricas de performance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;zk_avg_latency&lt;/code&gt;: latência média de operações&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_max_latency&lt;/code&gt;: latência máxima&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_packets_received&lt;/code&gt;: pacotes recebidos por segundo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_packets_sent&lt;/code&gt;: pacotes enviados por segundo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Métricas de saúde:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;zk_followers&lt;/code&gt;: número de seguidores conectados&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_pending_syncs&lt;/code&gt;: sincronizações pendentes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_open_file_descriptor_count&lt;/code&gt;: descritores de arquivo abertos&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zk_max_file_descriptor_count&lt;/code&gt;: limite de descritores&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ferramentas de monitoramento
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMX com Prometheus:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# prometheus.yml&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;zookeeper'&lt;/span&gt;
  &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;zk1:9999'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;zk2:9999'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;zk3:9999'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Comandos de diagnóstico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar conexões ativas&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;cons | nc localhost 2181

&lt;span class="c"&gt;# Verificar watches ativos  &lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;wchs | nc localhost 2181

&lt;span class="c"&gt;# Verificar estatísticas detalhadas&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;mntr | nc localhost 2181
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting comum
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problemas de conectividade
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sintoma:&lt;/strong&gt; Clientes não conseguem conectar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar se porta está aberta&lt;/span&gt;
telnet zk1 2181

&lt;span class="c"&gt;# Verificar logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/zookeeper/zookeeper.log

&lt;span class="c"&gt;# Verificar configuração de rede&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;2181
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solução:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verificar firewall e regras de rede&lt;/li&gt;
&lt;li&gt;Confirmar configuração de &lt;code&gt;clientPort&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Validar DNS/resolução de nomes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Split-brain e quorum
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sintoma:&lt;/strong&gt; Ensemble não consegue formar quorum&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024-01-15 10:30:00 WARN [QuorumPeer] Not enough followers present, giving up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Diagnóstico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar status de cada nó&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;server &lt;span class="k"&gt;in &lt;/span&gt;zk1 zk2 zk3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== &lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt;
    &lt;span class="nb"&gt;echo stat&lt;/span&gt; | nc &lt;span class="nv"&gt;$server&lt;/span&gt; 2181 | &lt;span class="nb"&gt;grep &lt;/span&gt;Mode
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solução:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Garantir que maioria dos nós esteja ativa&lt;/li&gt;
&lt;li&gt;Verificar conectividade entre servidores&lt;/li&gt;
&lt;li&gt;Reiniciar nós em sequência se necessário&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance degradada
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sintoma:&lt;/strong&gt; Alta latência em operações&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar métricas de latência&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;mntr | nc localhost 2181 | &lt;span class="nb"&gt;grep &lt;/span&gt;latency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Otimizações:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aumentar heap JVM se necessário&lt;/li&gt;
&lt;li&gt;Configurar &lt;code&gt;preAllocSize&lt;/code&gt; adequado&lt;/li&gt;
&lt;li&gt;Mover &lt;code&gt;dataDir&lt;/code&gt; para SSD&lt;/li&gt;
&lt;li&gt;Ajustar &lt;code&gt;snapCount&lt;/code&gt; conforme carga&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Evolução: Kafka sem Zookeeper (KRaft)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Limitações do Zookeeper
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Complexidade operacional:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Componente adicional para gerenciar&lt;/li&gt;
&lt;li&gt;Configuração e monitoramento separados&lt;/li&gt;
&lt;li&gt;Ponto de falha adicional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitações de escalabilidade:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Metadados limitados pela capacidade do Zookeeper&lt;/li&gt;
&lt;li&gt;Latência adicional para operações administrativas&lt;/li&gt;
&lt;li&gt;Complexidade de backup e recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  KRaft (Kafka Raft)
&lt;/h3&gt;

&lt;p&gt;A partir do Kafka 2.8, foi introduzido o &lt;strong&gt;KRaft mode&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kafka com Zookeeper:
Kafka Brokers ←→ Zookeeper Ensemble

Kafka com KRaft:
Kafka Controllers + Kafka Brokers (self-managed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Vantagens do KRaft:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicidade&lt;/strong&gt;: menos componentes para gerenciar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: menor latência para metadados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt;: suporte a milhões de partições&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência&lt;/strong&gt;: modelo de dados unificado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Status atual:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kafka 3.3+: KRaft production-ready&lt;/li&gt;
&lt;li&gt;Migração gradual do Zookeeper para KRaft&lt;/li&gt;
&lt;li&gt;Zookeeper ainda amplamente usado em produção&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Casos de uso além do Kafka
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Descoberta de serviços
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Registro dinâmico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Serviço se registra no Zookeeper&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;servicePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/services/user-service/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;instanceId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;servicePath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serviceInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; 
          &lt;span class="nc"&gt;ZooDefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OPEN_ACL_UNSAFE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
          &lt;span class="nc"&gt;CreateMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EPHEMERAL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Descoberta por clientes:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cliente descobre serviços disponíveis&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getChildren&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/services/user-service"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuração distribuída
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Configuração centralizada:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Atualizar configuração&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/config/app-settings"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Clientes recebem notificação automática via watch&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/config/app-settings"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ConfigWatcher&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coordenação de tarefas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lock distribuído:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Implementação de mutex distribuído&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;lockPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/locks/resource-x/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lockPath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; 
          &lt;span class="nc"&gt;ZooDefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OPEN_ACL_UNSAFE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
          &lt;span class="nc"&gt;CreateMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EPHEMERAL_SEQUENTIAL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Boas práticas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuração de produção
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ensemble sizing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3 nós&lt;/strong&gt;: desenvolvimento e testes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 nós&lt;/strong&gt;: produção com alta disponibilidade&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7+ nós&lt;/strong&gt;: apenas para casos muito críticos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hardware:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: 4+ cores para ensemble de produção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM&lt;/strong&gt;: 8GB+ com heap JVM de 4GB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disco&lt;/strong&gt;: SSD para &lt;code&gt;dataDir&lt;/code&gt; e &lt;code&gt;dataLogDir&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rede&lt;/strong&gt;: baixa latência entre nós do ensemble&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Segurança
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Autenticação:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# SASL/Kerberos
&lt;/span&gt;&lt;span class="py"&gt;authProvider.1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.apache.zookeeper.server.auth.SASLAuthenticationProvider&lt;/span&gt;
&lt;span class="py"&gt;requireClientAuthScheme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;sasl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Autorização:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ACLs para controle de acesso&lt;/span&gt;
&lt;span class="n"&gt;zk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/secure/path"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
          &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="no"&gt;ACL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ZooDefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Perms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ALL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"digest"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"user:password"&lt;/span&gt;&lt;span class="o"&gt;))),&lt;/span&gt;
          &lt;span class="nc"&gt;CreateMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PERSISTENT&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Backup e recovery
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Backup de dados:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backup do dataDir&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czf&lt;/span&gt; zk-backup-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;.tar.gz /var/lib/zookeeper

&lt;span class="c"&gt;# Backup via snapshot&lt;/span&gt;
zkServer.sh snapshot /var/lib/zookeeper/version-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Recovery:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Restaurar dados&lt;/span&gt;
service zookeeper stop
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/zookeeper/version-2/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; zk-backup-20240115.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; /
service zookeeper start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Apache Zookeeper é o alicerce que permite a operação confiável de sistemas distribuídos como Apache Kafka. Sua capacidade de fornecer coordenação, consistência e detecção de falhas de forma transparente torna possível construir arquiteturas complexas e resilientes.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>dataengineering</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Debezium: Capturando mudanças de dados em tempo real</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Sun, 28 Sep 2025 14:21:43 +0000</pubDate>
      <link>https://dev.to/programadriano/debezium-capturando-mudancas-de-dados-em-tempo-real-4060</link>
      <guid>https://dev.to/programadriano/debezium-capturando-mudancas-de-dados-em-tempo-real-4060</guid>
      <description>&lt;p&gt;Imagine que você tem um sistema de e-commerce com milhares de transações por minuto. Cada venda, atualização de estoque ou mudança de preço precisa ser refletida instantaneamente em diferentes sistemas: data warehouse, cache de produtos, sistema de recomendações, notificações push. Como garantir que todos esses sistemas recebam as mudanças em tempo real, sem sobrecarregar o banco principal?&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Debezium&lt;/strong&gt; é uma plataforma open-source que resolve exatamente esse problema, capturando mudanças de dados diretamente do log de transações dos bancos de dados e transmitindo-as como eventos de streaming.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é Debezium
&lt;/h2&gt;

&lt;p&gt;Debezium é uma plataforma distribuída para Change Data Capture (CDC) que monitora bancos de dados e captura mudanças em tempo real, transformando cada inserção, atualização e deleção em eventos que podem ser consumidos por diferentes aplicações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Características principais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em Kafka Connect&lt;/strong&gt;: utiliza a infraestrutura robusta do Apache Kafka&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suporte multi-banco&lt;/strong&gt;: SQL Server, PostgreSQL, MySQL, MongoDB, Oracle, Cassandra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tolerância a falhas&lt;/strong&gt;: recuperação automática e processamento exactly-once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema evolution&lt;/strong&gt;: adaptação automática a mudanças de esquema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baixa latência&lt;/strong&gt;: captura mudanças em milissegundos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O problema que o Debezium resolve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Antes do Debezium: integração tradicional
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Polling periódico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Executado a cada minuto&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;data_atualizacao&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;ultimo_processamento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problemas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latência alta&lt;/strong&gt;: mudanças só são detectadas no próximo polling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carga no banco&lt;/strong&gt;: queries constantes impactam performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perda de dados&lt;/strong&gt;: mudanças podem ser perdidas entre polls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexidade&lt;/strong&gt;: lógica de controle de timestamp em cada tabela&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Triggers SQL:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;tr_produto_change&lt;/span&gt; 
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;produtos&lt;/span&gt; &lt;span class="k"&gt;AFTER&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt;
&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="c1"&gt;-- Lógica para enviar mudanças&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problemas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acoplamento forte&lt;/strong&gt;: lógica de integração no banco de dados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: overhead transacional em cada operação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manutenção&lt;/strong&gt;: triggers complexas e difíceis de debugar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falhas&lt;/strong&gt;: se o sistema externo falhar, a transação pode falhar&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Depois do Debezium: streaming de mudanças
&lt;/h3&gt;

&lt;p&gt;O Debezium resolve esses problemas capturando mudanças diretamente do &lt;strong&gt;log de transações&lt;/strong&gt; (WAL no PostgreSQL, binlog no MySQL, CDC no SQL Server), sem impactar as operações do banco.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como o Debezium funciona
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Arquitetura de alto nível
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Banco de Dados] → [Log de Transações] → [Debezium Connector] → [Kafka] → [Consumidores]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fluxo detalhado
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Monitoramento do log&lt;/strong&gt;: Debezium lê continuamente o log de transações&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parsing de mudanças&lt;/strong&gt;: converte entradas do log em eventos estruturados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publicação no Kafka&lt;/strong&gt;: envia eventos para tópicos específicos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumo distribuído&lt;/strong&gt;: aplicações consomem eventos conforme necessário&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Formato dos eventos
&lt;/h3&gt;

&lt;p&gt;Cada mudança gera um evento JSON com estrutura padronizada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;estado&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;anterior&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;registro&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;estado&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;atual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;registro&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.9.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"connector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sqlserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecommerce"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ts_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1640995200000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"snapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"db"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EcommerceCDC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dbo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"produtos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"change_lsn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00000025:00000110:0005"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"op"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"u"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;c=create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;u=update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;d=delete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;r=read&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ts_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1640995200000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conectores disponíveis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SQL Server Connector
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em&lt;/strong&gt;: SQL Server CDC (Change Data Capture)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versões suportadas&lt;/strong&gt;: SQL Server 2017+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursos&lt;/strong&gt;: snapshot inicial, schema evolution, filtros por tabela&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuração&lt;/strong&gt;: requer CDC habilitado no banco&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostgreSQL Connector
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em&lt;/strong&gt;: Logical Replication (WAL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versões suportadas&lt;/strong&gt;: PostgreSQL 10+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursos&lt;/strong&gt;: replication slots, publication/subscription&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: baixíssima latência (&amp;lt; 10ms)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MySQL Connector
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em&lt;/strong&gt;: Binary Log (binlog)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versões suportadas&lt;/strong&gt;: MySQL 5.7+, MariaDB 10.1+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursos&lt;/strong&gt;: GTID support, multi-master&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuração&lt;/strong&gt;: requer binlog habilitado&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MongoDB Connector
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em&lt;/strong&gt;: Change Streams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versões suportadas&lt;/strong&gt;: MongoDB 3.6+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursos&lt;/strong&gt;: sharded clusters, replica sets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Formato&lt;/strong&gt;: eventos nativos MongoDB&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Debezium representa uma evolução natural das estratégias de integração de dados, oferecendo uma solução robusta e escalável para captura de mudanças em tempo real. &lt;/p&gt;

</description>
      <category>architecture</category>
      <category>database</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>Change Data Capture (CDC): Capturando mudanças em tempo real</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Sun, 28 Sep 2025 13:42:10 +0000</pubDate>
      <link>https://dev.to/programadriano/change-data-capture-cdc-capturando-mudancas-em-tempo-real-lcc</link>
      <guid>https://dev.to/programadriano/change-data-capture-cdc-capturando-mudancas-em-tempo-real-lcc</guid>
      <description>&lt;p&gt;Imagine que você precisa manter um sistema de relatórios sempre atualizado com as últimas vendas do seu e-commerce. Tradicionalmente, você executaria um processo ETL a cada hora para varrer toda a tabela de pedidos e identificar o que mudou. &lt;/p&gt;

&lt;p&gt;Mas e se houvesse uma forma mais inteligente?&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Change Data Capture (CDC)&lt;/strong&gt; é uma tecnologia que permite capturar e rastrear alterações em um banco de dados de forma automática e eficiente. No SQL Server, o CDC registra inserções, atualizações e deleções em tabelas específicas, permitindo que aplicações processem essas mudanças em tempo quase real.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema que o CDC resolve
&lt;/h2&gt;

&lt;p&gt;Antes do CDC, as organizações enfrentavam diversos desafios para manter sistemas integrados:&lt;/p&gt;

&lt;h3&gt;
  
  
  Latência nas integrações
&lt;/h3&gt;

&lt;p&gt;Os processos ETL tradicionais executam em lotes (batch), geralmente de hora em hora ou diariamente. Isso significa que decisões críticas de negócio são tomadas com dados desatualizados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impacto no desempenho
&lt;/h3&gt;

&lt;p&gt;Para descobrir "o que mudou", os sistemas precisam varrer tabelas inteiras, comparando timestamps ou fazendo joins complexos. Isso gera:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alto consumo de CPU e I/O&lt;/li&gt;
&lt;li&gt;Bloqueios e contenção no banco transacional&lt;/li&gt;
&lt;li&gt;Degradação da experiência do usuário final&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Soluções inadequadas
&lt;/h3&gt;

&lt;p&gt;Alternativas como triggers SQL criam acoplamento forte entre sistemas e adicionam overhead transacional, podendo causar efeitos colaterais indesejados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Falta de rastreabilidade
&lt;/h3&gt;

&lt;p&gt;Sem um mecanismo adequado, é difícil saber exatamente o que mudou, quando e em qual ordem, dificultando auditoria e troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como o CDC resolve esses problemas
&lt;/h2&gt;

&lt;p&gt;O CDC oferece uma abordagem elegante e eficiente:&lt;/p&gt;

&lt;h3&gt;
  
  
  Captura automática e incremental
&lt;/h3&gt;

&lt;p&gt;O CDC monitora o log de transações do SQL Server e captura automaticamente todas as mudanças (INSERT, UPDATE, DELETE) sem impactar a aplicação principal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Baixo acoplamento
&lt;/h3&gt;

&lt;p&gt;Não requer modificações no código da aplicação. O CDC funciona de forma transparente, lendo o log de transações e materializando as mudanças em tabelas especiais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ordem garantida
&lt;/h3&gt;

&lt;p&gt;Cada mudança recebe um LSN (Log Sequence Number) único, garantindo que os consumidores possam processar as alterações na ordem correta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Múltiplos consumidores
&lt;/h3&gt;

&lt;p&gt;Diferentes sistemas podem consumir as mesmas mudanças de forma independente, cada um mantendo seu próprio checkpoint de progresso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como o CDC funciona na prática
&lt;/h2&gt;

&lt;p&gt;O funcionamento do CDC no SQL Server segue um fluxo bem definido:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Habilitação
&lt;/h3&gt;

&lt;p&gt;O CDC é habilitado primeiro no nível do banco de dados e depois em tabelas específicas. Para cada tabela, são criadas "change tables" que armazenam as mudanças capturadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Captura
&lt;/h3&gt;

&lt;p&gt;Jobs do SQL Server Agent executam periodicamente para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ler o log de transações&lt;/li&gt;
&lt;li&gt;Identificar mudanças nas tabelas monitoradas&lt;/li&gt;
&lt;li&gt;Inserir essas mudanças nas change tables correspondentes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Consumo
&lt;/h3&gt;

&lt;p&gt;Aplicações e processos ETL consomem as mudanças através de funções especiais que permitem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ler mudanças entre dois pontos no tempo (LSNs)&lt;/li&gt;
&lt;li&gt;Escolher entre "all changes" (todas as operações) ou "net changes" (resultado final)&lt;/li&gt;
&lt;li&gt;Manter checkpoints para processamento incremental&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Limpeza
&lt;/h3&gt;

&lt;p&gt;Um job de limpeza remove automaticamente mudanças antigas conforme a política de retenção configurada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo prático: implementando CDC
&lt;/h2&gt;

&lt;p&gt;Vamos ver como habilitar e usar o CDC em uma tabela de clientes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 1) Habilitar CDC no banco de dados&lt;/span&gt;

&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sp_cdc_enable_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 2) Habilitar CDC na tabela específica&lt;/span&gt;

&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sp_cdc_enable_table&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;source_schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'dbo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;source_name&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'Clientes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;role_name&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;-- ou uma role para controle de acesso&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;supports_net_changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;-- requer chave primária na tabela&lt;/span&gt;

&lt;span class="c1"&gt;-- 3) Definir janela de leitura das mudanças&lt;/span&gt;
&lt;span class="k"&gt;DECLARE&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;from_lsn&lt;/span&gt; &lt;span class="nb"&gt;BINARY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_cdc_get_min_lsn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dbo_Clientes'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;DECLARE&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;to_lsn&lt;/span&gt;   &lt;span class="nb"&gt;BINARY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_cdc_get_max_lsn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;-- 4) Consultar todas as mudanças capturadas&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;__&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;-- 1=DELETE, 2=INSERT, 3=UPDATE (antes), 4=UPDATE (depois)&lt;/span&gt;
    &lt;span class="n"&gt;__&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;start_lsn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;-- LSN da transação&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;cdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_cdc_get_all_changes_dbo_Clientes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;from_lsn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;to_lsn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após executar mudanças na tabela &lt;code&gt;Clientes&lt;/code&gt;, você verá os registros capturados com informações sobre o tipo de operação e o conteúdo alterado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usar o CDC
&lt;/h2&gt;

&lt;p&gt;O CDC é especialmente útil nos seguintes cenários:&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrações em tempo real
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sincronização de dados entre sistemas&lt;/li&gt;
&lt;li&gt;Alimentação de dashboards e relatórios em tempo real&lt;/li&gt;
&lt;li&gt;Notificações automáticas baseadas em mudanças de dados&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Arquiteturas modernas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event-driven architecture&lt;/strong&gt;: CDC gera eventos para cada mudança&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microserviços&lt;/strong&gt;: sincronização de dados entre serviços independentes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data streaming&lt;/strong&gt;: integração com Apache Kafka, Azure Event Hubs, AWS Kinesis&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Casos de uso específicos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce&lt;/strong&gt;: atualização de estoque em tempo real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sistemas financeiros&lt;/strong&gt;: auditoria e compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoT e telemetria&lt;/strong&gt;: processamento de dados de sensores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business Intelligence&lt;/strong&gt;: ETL incremental para data warehouses&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ferramentas e tecnologias que trabalham com CDC
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Plataformas de streaming
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache Kafka&lt;/strong&gt;: através do Kafka Connect com conectores CDC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Event Hubs&lt;/strong&gt;: integração nativa com Azure Data Factory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Kinesis&lt;/strong&gt;: usando AWS DMS (Database Migration Service)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confluent Platform&lt;/strong&gt;: conectores especializados para SQL Server&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Soluções de replicação
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debezium&lt;/strong&gt;: plataforma open-source para CDC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Striim&lt;/strong&gt;: streaming de dados em tempo real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qlik Replicate&lt;/strong&gt;: replicação de dados empresarial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HVR&lt;/strong&gt;: replicação de dados híbrida&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparação com outras abordagens
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Abordagem&lt;/th&gt;
&lt;th&gt;Latência&lt;/th&gt;
&lt;th&gt;Impacto no OLTP&lt;/th&gt;
&lt;th&gt;Complexidade&lt;/th&gt;
&lt;th&gt;Auditoria&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CDC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Mínimo&lt;/td&gt;
&lt;td&gt;Média&lt;/td&gt;
&lt;td&gt;Completa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Change Tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Mínimo&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Limitada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Triggers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Alto&lt;/td&gt;
&lt;td&gt;Alta&lt;/td&gt;
&lt;td&gt;Customizável&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ETL Batch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alta&lt;/td&gt;
&lt;td&gt;Médio&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Limitada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Temporal Tables&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Baixo&lt;/td&gt;
&lt;td&gt;Baixa&lt;/td&gt;
&lt;td&gt;Histórico&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Quando usar CDC
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cenários ideais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Integrações que exigem baixa latência (minutos ou segundos)&lt;/li&gt;
&lt;li&gt;Sistemas que precisam de auditoria detalhada de mudanças&lt;/li&gt;
&lt;li&gt;Arquiteturas event-driven ou baseadas em streaming&lt;/li&gt;
&lt;li&gt;Sincronização entre múltiplos sistemas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quando considerar alternativas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Processamento batch diário é suficiente para o negócio&lt;/li&gt;
&lt;li&gt;Mudanças nos dados são muito raras&lt;/li&gt;
&lt;li&gt;Infraestrutura não suporta jobs adicionais ou armazenamento extra&lt;/li&gt;
&lt;li&gt;Sistemas legados sem capacidade de modernização&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Change Data Capture representa uma evolução natural das estratégias de integração de dados, oferecendo uma solução elegante para os desafios de latência, performance e rastreabilidade que afetam sistemas modernos.&lt;/p&gt;

&lt;p&gt;Com o CDC, organizações podem construir arquiteturas mais responsivas e resilientes, mantendo a integridade dos dados e reduzindo significativamente a complexidade das integrações.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>database</category>
      <category>architecture</category>
      <category>sql</category>
    </item>
    <item>
      <title>Streams de Dados: Processamento de Informações em Tempo Real</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Sun, 28 Sep 2025 00:44:43 +0000</pubDate>
      <link>https://dev.to/programadriano/streams-de-dados-processamento-de-informacoes-em-tempo-real-2ccm</link>
      <guid>https://dev.to/programadriano/streams-de-dados-processamento-de-informacoes-em-tempo-real-2ccm</guid>
      <description>&lt;h2&gt;
  
  
  O que são Streams de Dados?
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;stream de dados&lt;/strong&gt; é um fluxo contínuo e potencialmente infinito de registros de dados que são gerados e processados em tempo real.&lt;/p&gt;

&lt;p&gt;Diferentemente dos dados tradicionais em lote (batch), os streams representam informações que fluem constantemente, como um rio que nunca para de correr.&lt;/p&gt;

&lt;p&gt;Imagine dados como gotas de chuva caindo continuamente — cada gota representa um evento ou registro, e o conjunto forma um fluxo constante de informações que precisa ser capturado e processado no momento em que acontece.&lt;/p&gt;

&lt;h2&gt;
  
  
  Características Fundamentais dos Streams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Continuidade Temporal&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os dados chegam de forma contínua, sem intervalos predefinidos. Em teoria um stream pode ser infinito, mas na prática aplicam-se janelas de tempo (time windows) para agrupar e processar eventos em blocos lógicos.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Ordem Temporal&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os eventos possuem uma sequência associada ao tempo (timestamp). Porém, em sistemas distribuídos é comum chegarem fora de ordem; por isso usam-se watermarks, tolerância a eventos atrasados e configuração de atraso máximo (max out-of-orderness), sobretudo quando se processa por event-time (tempo do evento) em vez de processing-time (tempo de processamento).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Imutabilidade Lógica&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Um evento, uma vez publicado, &lt;strong&gt;não deve ser alterado&lt;/strong&gt;. Correções ou mudanças são feitas através da publicação de novos eventos que complementam ou invalidam os anteriores, preservando assim a integridade histórica.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Volume Variável&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A taxa de chegada dos dados pode variar drasticamente — desde alguns eventos por minuto até milhões por segundo — exigindo sistemas capazes de escalar dinamicamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Baixa Latência&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O objetivo é processar os dados com mínima demora (geralmente em milissegundos ou segundos), garantindo que as informações sejam relevantes no momento em que ocorrem; em muitos cenários busca-se near-real-time (ordem de segundos), e não tempo real estrito. O nível de latência aceitável depende do caso de uso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de Streams de Dados
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Event Streams (Streams de Eventos)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Representam ações ou mudanças de estado que acontecem no sistema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cliques em um website&lt;/li&gt;
&lt;li&gt;Transações bancárias&lt;/li&gt;
&lt;li&gt;Login/logout de usuários&lt;/li&gt;
&lt;li&gt;Mudanças de status de pedidos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Sensor Streams (Streams de Sensores)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Dados coletados continuamente de dispositivos físicos ou virtuais.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temperatura de servidores&lt;/li&gt;
&lt;li&gt;Localização GPS de veículos&lt;/li&gt;
&lt;li&gt;Batimentos cardíacos de wearables&lt;/li&gt;
&lt;li&gt;Consumo de energia de equipamentos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Log Streams (Streams de Logs)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Registros de atividades de sistemas e aplicações.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs de aplicações web&lt;/li&gt;
&lt;li&gt;Registros de acesso a APIs&lt;/li&gt;
&lt;li&gt;Eventos de segurança&lt;/li&gt;
&lt;li&gt;Métricas de performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Apache Kafka e Streams de Dados
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Apache Kafka&lt;/strong&gt; é uma das principais plataformas para trabalhar com streams de dados, oferecendo uma infraestrutura robusta para capturar, armazenar e processar fluxos de informações em tempo real.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Como o Kafka Gerencia Streams&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Tópicos como Streams&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;No Kafka, cada tópico representa um stream de dados específico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tópico "user-clicks"   = Stream de cliques dos usuários
Tópico "transactions"  = Stream de transações financeiras
Tópico "sensor-data"   = Stream de dados de sensores IoT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;2. Particionamento para Paralelismo&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;O Kafka divide cada stream (tópico) em partições, permitindo escalabilidade e paralelismo no consumo. Dentro de cada partição a ordem é garantida, mas entre partições não há ordenação global:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stream "pedidos-ecommerce"
├── Partição 0: Pedidos região Norte
├── Partição 1: Pedidos região Sul
├── Partição 2: Pedidos região Sudeste
└── Partição 3: Pedidos região Centro-Oeste
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em um consumer group, cada partição é atribuída a no máximo um consumidor simultaneamente, possibilitando paralelismo e balanceamento de carga. Ao aumentar o número de consumidores no grupo (até o número de partições), o processamento é distribuído automaticamente.&lt;/p&gt;

&lt;p&gt;Além disso, a escolha da chave de partição determina a distribuição dos eventos entre as partições, afetando o balanceamento de carga e a preservação de ordem por entidade (por exemplo, por &lt;code&gt;user_id&lt;/code&gt; ou &lt;code&gt;order_id&lt;/code&gt;). Escolhas inadequadas podem criar hot partitions e reduzir o throughput.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Retenção Configurável&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Os streams podem ser mantidos por tempo determinado (horas, dias, semanas) ou por tamanho, permitindo reprocessamento quando necessário e atendendo requisitos regulatórios.&lt;/p&gt;

&lt;p&gt;Os streams de dados representam uma mudança fundamental na forma como processamos informações, movendo-nos de análises retrospectivas para &lt;strong&gt;insights e ações em tempo real&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O Apache Kafka, com seu ecossistema robusto, é uma das principais ferramentas para construir pipelines de streaming &lt;strong&gt;confiáveis, escaláveis e tolerantes a falhas&lt;/strong&gt; — mas não a única. Tecnologias como Apache Flink, Spark Streaming e Redpanda também desempenham papéis importantes nesse ecossistema.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>data</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>Introdução ao Apache Kafka</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Sat, 27 Sep 2025 23:03:34 +0000</pubDate>
      <link>https://dev.to/programadriano/introducao-ao-apache-kafka-2haj</link>
      <guid>https://dev.to/programadriano/introducao-ao-apache-kafka-2haj</guid>
      <description>&lt;p&gt;O Apache Kafka é uma plataforma distribuída de streaming de dados em tempo real, desenvolvida originalmente pelo LinkedIn e posteriormente doada à Apache Software Foundation. &lt;/p&gt;

&lt;p&gt;O Kafka foi projetado para lidar com grandes volumes de dados de forma eficiente, confiável e escalável.&lt;/p&gt;

&lt;p&gt;Em termos simples, o Kafka funciona como um "sistema nervoso" para aplicações modernas, permitindo que diferentes sistemas se comuniquem através do envio e recebimento de mensagens em tempo real.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são streams de dados?
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;stream de dados&lt;/strong&gt; é um fluxo contínuo de informações que são geradas constantemente por diversas fontes. Imagine um rio que nunca para de fluir - os dados são como a água, sempre em movimento, chegando continuamente de diferentes afluentes (fontes de dados).&lt;/p&gt;

&lt;h3&gt;
  
  
  Características dos Streams de Dados:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Contínuos&lt;/strong&gt;: Os dados chegam constantemente, sem interrupção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ordenados&lt;/strong&gt;: Geralmente possuem uma sequência temporal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imutáveis&lt;/strong&gt;: Uma vez criados, os dados não são alterados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Potencialmente infinitos&lt;/strong&gt;: O fluxo pode continuar indefinidamente&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exemplos de Streams de Dados:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logs de aplicação&lt;/strong&gt;: Registros de atividades de um sistema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cliques em websites&lt;/strong&gt;: Cada interação do usuário gera um evento&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transações financeiras&lt;/strong&gt;: Pagamentos, transferências, compras&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dados de sensores IoT&lt;/strong&gt;: Temperatura, umidade, localização GPS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feeds de redes sociais&lt;/strong&gt;: Posts, likes, comentários em tempo real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Métricas de sistema&lt;/strong&gt;: CPU, memória, rede de servidores&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conceitos Fundamentais do Kafka
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Topics (Tópicos)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Um tópico é como um "canal" ou "categoria" onde as mensagens são organizadas. É similar a uma pasta onde você agrupa emails relacionados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tópico "pedidos-ecommerce" para todas as compras&lt;/li&gt;
&lt;li&gt;Tópico "logs-aplicacao" para registros do sistema&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Producers (Produtores)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;São aplicações que enviam dados para o Kafka. Eles "produzem" mensagens e as enviam para tópicos específicos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma aplicação web que envia dados de cliques dos usuários&lt;/li&gt;
&lt;li&gt;Um sistema de pagamento que registra transações&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Consumers (Consumidores)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;São aplicações que leem dados do Kafka. Eles "consomem" mensagens dos tópicos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um sistema de recomendação que analisa cliques&lt;/li&gt;
&lt;li&gt;Um dashboard que mostra métricas em tempo real&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Partitions (Partições)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cada tópico é dividido em partições para permitir paralelismo e escalabilidade. É como dividir uma estrada em várias faixas para aumentar o tráfego.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Brokers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;São os servidores que compõem o cluster Kafka. Eles armazenam os dados e servem as requisições dos producers e consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como Funciona o Kafka?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Producer] -----&amp;gt; [Kafka Cluster] -----&amp;gt; [Consumer]
    |                   |                    |
Aplicação Web      Tópico: "eventos"    Sistema de
envia eventos      Partições: 0,1,2     Análise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Producer&lt;/strong&gt; envia uma mensagem para um tópico&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka&lt;/strong&gt; armazena a mensagem em uma partição&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumer&lt;/strong&gt; lê a mensagem do tópico&lt;/li&gt;
&lt;li&gt;A mensagem permanece no Kafka por um tempo configurável&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Casos de uso mais Comuns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Arquitetura de Microserviços&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Kafka facilita a comunicação entre diferentes serviços, permitindo que eles troquem informações de forma assíncrona.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Event Sourcing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Armazena todos os eventos que acontecem no sistema, permitindo reconstruir o estado atual a partir do histórico.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;CQRS (Command Query Responsibility Segregation)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Separa operações de leitura e escrita, usando Kafka para sincronizar os dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Data Pipeline&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Move dados entre diferentes sistemas (bancos de dados, data warehouses, sistemas de análise).&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Stream Processing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Processa dados em tempo real para gerar insights imediatos.&lt;/p&gt;

&lt;p&gt;Em resumo o Apache Kafka revolucionou a forma como lidamos com dados em tempo real. Sua capacidade de processar grandes volumes de dados com baixa latência o torna essencial para aplicações modernas que precisam reagir rapidamente a eventos.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>data</category>
      <category>backend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Saga Pattern</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Fri, 26 Sep 2025 21:12:27 +0000</pubDate>
      <link>https://dev.to/programadriano/saga-pattern-52h0</link>
      <guid>https://dev.to/programadriano/saga-pattern-52h0</guid>
      <description>&lt;p&gt;O &lt;strong&gt;Saga Pattern&lt;/strong&gt; é um padrão de design que gerencia transações distribuídas em arquiteturas de microsserviços. Ele resolve o problema de manter consistência de dados quando uma operação de negócio precisa ser executada através de múltiplos serviços independentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Problema das transações distribuídas
&lt;/h2&gt;

&lt;p&gt;Em arquiteturas monolíticas, podemos usar transações ACID do banco de dados para garantir consistência. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u6z82g9anu3rxohx00a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u6z82g9anu3rxohx00a.png" alt=" " width="728" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porém, em microsserviços:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cada serviço&lt;/strong&gt; tem seu próprio banco de dados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transações locais&lt;/strong&gt; não podem abranger múltiplos serviços&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-Phase Commit (2PC)&lt;/strong&gt; é complexo e pode causar bloqueios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falhas parciais&lt;/strong&gt; podem deixar o sistema em estado inconsistente&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvcjv544yqwq9hk8zw45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvcjv544yqwq9hk8zw45.png" alt=" " width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo do Problema:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;E-commerce - Processamento de Pedido:
1. Serviço de Pedidos: Criar pedido
2. Serviço de Pagamento: Processar pagamento  
3. Serviço de Estoque: Reservar produtos
4. Serviço de Entrega: Agendar entrega

E se o pagamento falhar após criar o pedido?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como o Saga Pattern resolve ?
&lt;/h2&gt;

&lt;p&gt;O Saga divide uma transação distribuída em uma &lt;strong&gt;sequência de transações&lt;/strong&gt;. Cada transação atualiza dados dentro de um único serviço e publica eventos ou mensagens para acionar a próxima transação local na saga.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de Saga Pattern
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Choreography Saga (Coreografia)
&lt;/h3&gt;

&lt;p&gt;Cada serviço produz e escuta eventos para coordenar o fluxo da saga de forma &lt;strong&gt;descentralizada&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Como Funciona:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Serviço A executa uma transação&lt;/li&gt;
&lt;li&gt;Publica um evento&lt;/li&gt;
&lt;li&gt;Serviço B escuta o evento e executa sua transação&lt;/li&gt;
&lt;li&gt;Publica seu próprio evento&lt;/li&gt;
&lt;li&gt;O processo continua até completar ou falhar&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Orchestration Saga (Orquestração)
&lt;/h3&gt;

&lt;p&gt;Um &lt;strong&gt;orquestrador central&lt;/strong&gt; coordena todas as transações e decide qual serviço chamar em seguida.&lt;/p&gt;

&lt;h4&gt;
  
  
  Como Funciona:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Orquestrador inicia a saga&lt;/li&gt;
&lt;li&gt;Chama serviço A e aguarda resposta&lt;/li&gt;
&lt;li&gt;Com base na resposta, chama serviço B&lt;/li&gt;
&lt;li&gt;Continua coordenando até completar ou falhar&lt;/li&gt;
&lt;li&gt;Em caso de falha, executa compensações na ordem reversa&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O Saga Pattern não é uma bala de prata, mas quando aplicado corretamente, permite construir sistemas distribuídos resilientes e escaláveis que mantêm consistência de dados mesmo em cenários complexos de falha.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Introdução ao Event Sourcing</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Fri, 26 Sep 2025 21:01:55 +0000</pubDate>
      <link>https://dev.to/programadriano/introducao-ao-event-sourcing-oa2</link>
      <guid>https://dev.to/programadriano/introducao-ao-event-sourcing-oa2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Event Sourcing&lt;/strong&gt; é um padrão arquitetural onde todas as mudanças no estado de uma aplicação são armazenadas como uma sequência de eventos imutáveis. Em vez de persistir apenas o estado atual dos dados, o Event Sourcing mantém um registro completo de todos os eventos que levaram ao estado atual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceitos Fundamentais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Eventos
&lt;/h3&gt;

&lt;p&gt;Os eventos representam fatos que aconteceram no passado e são &lt;strong&gt;imutáveis&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Cada evento contém:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timestamp&lt;/strong&gt;: quando o evento ocorreu&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tipo&lt;/strong&gt;: que tipo de evento é&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dados&lt;/strong&gt;: informações específicas do evento&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata&lt;/strong&gt;: informações adicionais (usuário, versão, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uuid-123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ContaCriada"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-01-15T10:30:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aggregateId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"conta-456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"numeroConta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12345-6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"titular"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"João Silva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"saldoInicial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1000.00&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas como ele funciona? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Comando&lt;/strong&gt; é recebido pela aplicação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregate&lt;/strong&gt; processa o comando&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventos&lt;/strong&gt; são gerados como resultado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventos&lt;/strong&gt; são persistidos no Event Store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Projeções&lt;/strong&gt; são atualizadas com base nos novos eventos&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Exemplo Prático - Sistema Bancário:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Estado Inicial: Conta não existe

Eventos:
1. ContaCriada { numeroConta: "12345", saldo: 1000 }
2. DepositoRealizado { valor: 500 }
3. SaqueRealizado { valor: 200 }
4. DepositoRealizado { valor: 100 }

Estado Final: Conta "12345" com saldo de 1400
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Vantagens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Auditoria Completa&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Histórico completo de todas as mudanças&lt;/li&gt;
&lt;li&gt;Capacidade de responder "como chegamos aqui?"&lt;/li&gt;
&lt;li&gt;Conformidade regulatória facilitada&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Reconstrução de Estado&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Estado pode ser reconstruído a qualquer momento&lt;/li&gt;
&lt;li&gt;Possibilidade de "time travel" para qualquer ponto no tempo&lt;/li&gt;
&lt;li&gt;Debugging e análise histórica simplificados&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Flexibilidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Múltiplas projeções do mesmo conjunto de eventos&lt;/li&gt;
&lt;li&gt;Adição de novas funcionalidades sem migração de dados&lt;/li&gt;
&lt;li&gt;Suporte a diferentes modelos de leitura&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Escalabilidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Separação entre escrita (eventos) e leitura (projeções)&lt;/li&gt;
&lt;li&gt;Otimização independente para cada caso de uso&lt;/li&gt;
&lt;li&gt;Paralelização de processamento&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Integração&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eventos podem ser publicados para outros sistemas&lt;/li&gt;
&lt;li&gt;Base natural para arquiteturas orientadas a eventos&lt;/li&gt;
&lt;li&gt;Facilita a implementação de CQRS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Desvantagens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Complexidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Curva de aprendizado íngreme&lt;/li&gt;
&lt;li&gt;Maior complexidade conceitual&lt;/li&gt;
&lt;li&gt;Necessidade de gerenciar versionamento de eventos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Performance de Leitura&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reconstrução de estado pode ser lenta&lt;/li&gt;
&lt;li&gt;Necessidade de snapshots para agregados grandes&lt;/li&gt;
&lt;li&gt;Complexidade adicional nas consultas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Armazenamento&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Crescimento contínuo do volume de dados&lt;/li&gt;
&lt;li&gt;Necessidade de estratégias de arquivo/limpeza&lt;/li&gt;
&lt;li&gt;Maior uso de espaço em disco&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Eventual Consistency&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Projeções podem estar temporariamente desatualizadas&lt;/li&gt;
&lt;li&gt;Necessidade de lidar com inconsistências temporárias&lt;/li&gt;
&lt;li&gt;Complexidade adicional na UI&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>database</category>
    </item>
    <item>
      <title>CQRS — Command Query Responsibility Segregation</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Fri, 26 Sep 2025 19:32:13 +0000</pubDate>
      <link>https://dev.to/programadriano/cqrs-command-query-responsibility-segregation-30p</link>
      <guid>https://dev.to/programadriano/cqrs-command-query-responsibility-segregation-30p</guid>
      <description>&lt;p&gt;CQRS (Command Query Responsibility Segregation) é um padrão arquitetural que separa operações de escrita (commands) das operações de leitura (queries). &lt;/p&gt;

&lt;p&gt;Em vez de um único modelo que trata leituras e gravações, o sistema passa a ter modelos e caminhos distintos para cada responsabilidade, permitindo otimizações independentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceito básico
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Command&lt;/em&gt;: solicitação que altera o estado do sistema (ex.: CriarPedido, AtualizarCliente). Não retorna dados do modelo, apenas indicação de sucesso/erro.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Query&lt;/em&gt;: solicitação que recupera dados (ex.: ObterDetalhesPedido). Não altera estado — pode ser otimizada para leitura.&lt;/p&gt;

&lt;p&gt;A seguir temos uma imagem demonstrando como funciona este fluxo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn4dqdjvn4mr1l1n7c9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn4dqdjvn4mr1l1n7c9u.png" alt=" " width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpvzggcvxfmoy0dkeo4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpvzggcvxfmoy0dkeo4j.png" alt=" " width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CQRS — Command Query Responsibility Segregation</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Fri, 26 Sep 2025 19:32:13 +0000</pubDate>
      <link>https://dev.to/programadriano/cqrs-command-query-responsibility-segregation-2fma</link>
      <guid>https://dev.to/programadriano/cqrs-command-query-responsibility-segregation-2fma</guid>
      <description>&lt;p&gt;CQRS (Command Query Responsibility Segregation) é um padrão arquitetural que separa operações de escrita (commands) das operações de leitura (queries). &lt;/p&gt;

&lt;p&gt;Em vez de um único modelo que trata leituras e gravações, o sistema passa a ter modelos e caminhos distintos para cada responsabilidade, permitindo otimizações independentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceito básico
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Command&lt;/em&gt;: solicitação que altera o estado do sistema (ex.: CriarPedido, AtualizarCliente). Não retorna dados do modelo, apenas indicação de sucesso/erro.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Query&lt;/em&gt;: solicitação que recupera dados (ex.: ObterDetalhesPedido). Não altera estado — pode ser otimizada para leitura.&lt;/p&gt;

&lt;p&gt;A seguir temos uma imagem demonstrando como funciona este fluxo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn4dqdjvn4mr1l1n7c9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn4dqdjvn4mr1l1n7c9u.png" alt=" " width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNp1VNtO20AQ_ZXR9iVIISQEguNKlUiCChKUNEAr1eFhY48TF3vX2rUDAfM9lfreL-DHOru2mwToQ5SZ3XPOzM7FT8yXATKXhbG89xdcZXA-mQqAYRyhyLzyD2EPbs5uYXf3U3F6fT0mdz4ZDws4Hp959IPPPMN7vqLz4zSNI59nkRRwzleobqfC6Ol8Nlc8XcBQJgkXgb6KAvSmrHLBuLAL31WUoZ6yW8MBo2-DVqgChklwSkaMyquZlV8x1gBL_MbjKOCU15lYSp_D8VzhnAeygJFMeCS8-oAg5QlcUEHiSq06MkpjVDrSWVGmOBp4DWvAaLDzDjifmSrAyZKqJ3VRGoNcNxrWAjIp4gVqzecIAyXvUO3slDpXfM69sZI-3cIFF4RQBDbHmnrQIn3Ufp5xwNfyRgBF8Krk9lZfS9L8ib5pjabKW-_l18sf1FT4CfKgfDrcpAG1U627UKubp4GhVQhvLViTKM_ygdtd2SBZERPNlNBGHQ2ItZnNCIVUCXXukQdcl-V9-6qvOaoI6zky3qqeIiP7dogspLC8VT1EJW072U2AJZ6__C6qlEtEadu7CWZSCQ6j68tt6f9o2fWZoE6pCVhUa_b-A89o8ciq-1W5VY324DLPFNe1Fp9FZtIDfL9txReZRSGN5D_6llwB9b2JdrX0vU0frlAtI998BU4eqIWCx7TGQucJTcl2d_yYaz3CEISk3QijOHY_hGF45O83dWam3P2AvZnTbn80aAqCnQa9zaaak6xPsrRlKPyVC-nGTKQ0mgnEuOQKMkxSCSlXHBSGMWaRgvv6w7Hjuq4JbvS3BtcGY002V1HA3Ezl2GT0ANpZctmTwU9ZtsAEp8wlM-Dqbsqm4pk4KRc_pExqmpL5fMHckMeavNwO9ijiVM41hEqCaihzkTG307MSzH1iD8x1Oq2ec3TQ7zv7zmHb6TfZirn73V6r0z3qdA-7Trfbdw56z032aGO2W87R4fNfjwPzgQ" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>MassTransit: Simplificando Mensageria</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Thu, 25 Sep 2025 17:57:21 +0000</pubDate>
      <link>https://dev.to/programadriano/masstransit-simplificando-mensageria-2412</link>
      <guid>https://dev.to/programadriano/masstransit-simplificando-mensageria-2412</guid>
      <description>&lt;p&gt;Mensageria é um padrão de comunicação entre sistemas distribuídos que permite a troca de dados de forma assíncrona. Em vez de sistemas se comunicarem diretamente através de chamadas síncronas, eles enviam mensagens através de um intermediário (message broker), que garante a entrega e processamento adequado das informações.&lt;/p&gt;

&lt;p&gt;Este modelo de comunicação oferece diversas vantagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desacoplamento&lt;/strong&gt;: Os sistemas não precisam conhecer uns aos outros diretamente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt;: Capacidade de processar grandes volumes de mensagens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confiabilidade&lt;/strong&gt;: Garantia de entrega mesmo com falhas temporárias&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade&lt;/strong&gt;: Facilita a adição de novos consumidores e produtores&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MassTransit
&lt;/h2&gt;

&lt;p&gt;MassTransit é um framework .NET open-source que simplifica a implementação de sistemas baseados em mensageria. Criado para ser uma abstração de alto nível sobre diferentes brokers de mensagens, ele remove a complexidade de configuração e gerenciamento manual de filas, tópicos e exchanges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principais Características
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Abstração Unificada&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O MassTransit oferece uma API consistente independentemente do broker utilizado (RabbitMQ, Azure Service Bus, Amazon SQS, etc.). &lt;/p&gt;

&lt;p&gt;Isso significa que você pode trocar de broker sem alterar o código da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuração Declarativa&lt;/strong&gt;&lt;br&gt;
A configuração do MassTransit é feita através de código C# de forma fluente e intuitiva, eliminando a necessidade de configurações complexas em XML ou arquivos externos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrões Implementados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O framework implementa automaticamente padrões comuns de mensageria como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request/Response&lt;/li&gt;
&lt;li&gt;Publish/Subscribe&lt;/li&gt;
&lt;li&gt;Saga Pattern&lt;/li&gt;
&lt;li&gt;Routing Slip&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>csharp</category>
      <category>microservices</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Introdução ao RabbitMQ</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Wed, 24 Sep 2025 23:26:24 +0000</pubDate>
      <link>https://dev.to/programadriano/introducao-ao-rabbitmq-1o3m</link>
      <guid>https://dev.to/programadriano/introducao-ao-rabbitmq-1o3m</guid>
      <description>&lt;p&gt;O RabbitMQ é um &lt;strong&gt;message broker&lt;/strong&gt; (intermediador de mensagens) open-source que implementa o protocolo AMQP (Advanced Message Queuing Protocol).&lt;/p&gt;

&lt;p&gt;Desenvolvido em Erlang, ele atua como um intermediário entre aplicações, permitindo que elas se comuniquem de forma assíncrona através do envio e recebimento de mensagens.&lt;/p&gt;

&lt;p&gt;Imagine o RabbitMQ como um "correio digital" para suas aplicações: &lt;/p&gt;

&lt;p&gt;você deposita uma mensagem em uma "caixa postal" (queue) e ela é entregue ao destinatário quando ele estiver disponível para processá-la.&lt;/p&gt;

&lt;h3&gt;
  
  
  Características Principais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alta disponibilidade&lt;/strong&gt; e tolerância a falhas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt; horizontal e vertical&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade&lt;/strong&gt; de roteamento de mensagens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiplataforma&lt;/strong&gt; (Linux, Windows, macOS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Múltiplas linguagens&lt;/strong&gt; de programação suportadas&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conceitos Fundamentais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Producer (Produtor)
&lt;/h3&gt;

&lt;p&gt;A aplicação que &lt;strong&gt;envia&lt;/strong&gt; mensagens para o RabbitMQ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queue (Fila)
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;buffer&lt;/strong&gt; que armazena mensagens dentro do RabbitMQ. É como uma caixa postal que pode receber e armazenar mensagens até que um consumidor as processe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumer (Consumidor)
&lt;/h3&gt;

&lt;p&gt;A aplicação que &lt;strong&gt;recebe&lt;/strong&gt; e processa mensagens da queue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exchange (Roteador)
&lt;/h3&gt;

&lt;p&gt;Componente responsável por &lt;strong&gt;rotear&lt;/strong&gt; mensagens para as queues apropriadas baseado em regras de roteamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binding (Ligação)
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;conexão&lt;/strong&gt; entre um exchange e uma queue, definindo como as mensagens devem ser roteadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocolos Suportados
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AMQP 0-9-1 (Principal)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocolo nativo&lt;/strong&gt; do RabbitMQ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Binário&lt;/strong&gt; e eficiente&lt;/li&gt;
&lt;li&gt;Suporte completo a todas as funcionalidades&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Porta padrão:&lt;/strong&gt; 5672 (sem TLS) / 5671 (com TLS)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exemplo de conexão AMQP:
amqp://usuario:senha@localhost:5672/vhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MQTT (Message Queuing Telemetry Transport)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Protocolo &lt;strong&gt;leve&lt;/strong&gt; para dispositivos IoT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baixo consumo&lt;/strong&gt; de largura de banda&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Porta padrão:&lt;/strong&gt; 1883 (sem TLS) / 8883 (com TLS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  STOMP (Simple Text Oriented Messaging Protocol)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Protocolo &lt;strong&gt;baseado em texto&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simples&lt;/strong&gt; de implementar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Porta padrão:&lt;/strong&gt; 61613&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HTTP/HTTPS (via Management API)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interface REST&lt;/strong&gt; para administração&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Porta padrão:&lt;/strong&gt; 15672 (Management UI)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tipos de Exchange
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Direct Exchange
&lt;/h3&gt;

&lt;p&gt;Roteia mensagens baseado na &lt;strong&gt;routing key exata&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Routing Key: "user.created" → Queue: user_notifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Topic Exchange
&lt;/h3&gt;

&lt;p&gt;Permite roteamento com &lt;strong&gt;padrões&lt;/strong&gt; usando wildcards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pattern: "user.*" → Captura: "user.created", "user.updated", "user.deleted"
Pattern: "*.important" → Captura: "user.important", "order.important"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fanout Exchange
&lt;/h3&gt;

&lt;p&gt;Envia mensagens para &lt;strong&gt;todas&lt;/strong&gt; as queues conectadas (broadcast).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uma mensagem → Múltiplas queues simultaneamente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Headers Exchange
&lt;/h3&gt;

&lt;p&gt;Roteia baseado nos &lt;strong&gt;headers&lt;/strong&gt; da mensagem, não na routing key.&lt;/p&gt;

&lt;p&gt;Em resumo, o RabbitMQ é uma ferramenta fundamental para arquiteturas modernas, oferecendo uma solução robusta e flexível para comunicação assíncrona entre aplicações.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Event-Driven Architecture (EDA)</title>
      <dc:creator>Thiago da Silva Adriano</dc:creator>
      <pubDate>Wed, 27 Aug 2025 00:52:48 +0000</pubDate>
      <link>https://dev.to/programadriano/event-driven-architecture-eda-arquitetura-orientada-a-eventos-5ckb</link>
      <guid>https://dev.to/programadriano/event-driven-architecture-eda-arquitetura-orientada-a-eventos-5ckb</guid>
      <description>&lt;p&gt;A Arquitetura (EDA) é um padrão arquitetural onde componentes de software comunicam-se através da produção e consumo de eventos.&lt;/p&gt;

&lt;p&gt;Este paradigma promove baixo acoplamento, alta escalabilidade e responsividade em sistemas distribuídos modernos.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são Eventos?
&lt;/h2&gt;

&lt;p&gt;Um evento é uma mudança significativa de estado em um sistema. &lt;/p&gt;

&lt;p&gt;Ele representa algo que aconteceu no passado e é imutável. &lt;/p&gt;

&lt;p&gt;Exemplos comuns incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Evento de Negócio&lt;/strong&gt;: "Pedido foi criado", "Pagamento foi processado"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evento de Sistema&lt;/strong&gt;: "Usuário fez login", "Arquivo foi carregado"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evento de Domínio&lt;/strong&gt;: "Produto foi adicionado ao catálogo", "Estoque foi atualizado"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Características dos Eventos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Imutáveis&lt;/strong&gt;: Uma vez criados, não podem ser alterados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timestamped&lt;/strong&gt;: Possuem registro temporal de quando ocorreram&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextuais&lt;/strong&gt;: Carregam informações relevantes sobre a mudança de estado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assíncronos&lt;/strong&gt;: Processamento não requer resposta imediata&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Componentes Principais da EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Event Producers (Produtores de Eventos)
&lt;/h3&gt;

&lt;p&gt;Componentes responsáveis por detectar mudanças de estado e publicar eventos correspondentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo de um produtor de eventos&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orderData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orderData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Produz evento após criar o pedido&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OrderCreated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Event Consumers (Consumidores de Eventos)
&lt;/h3&gt;

&lt;p&gt;Componentes que escutam e reagem a eventos específicos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo de um consumidor de eventos&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailNotificationService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;handleOrderCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emailService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendOrderConfirmation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Event Bus/Broker (Barramento de Eventos)
&lt;/h3&gt;

&lt;p&gt;Middleware responsável por rotear eventos dos produtores para os consumidores.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Event Store (Armazenamento de Eventos)
&lt;/h3&gt;

&lt;p&gt;Sistema de persistência que mantém o histórico completo de eventos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Padrões Comuns em EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Event Streaming
&lt;/h3&gt;

&lt;p&gt;Fluxo contínuo de eventos processados em tempo real.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Event Sourcing
&lt;/h3&gt;

&lt;p&gt;Armazenamento de todas as mudanças de estado como sequência de eventos.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. CQRS (Command Query Responsibility Segregation)
&lt;/h3&gt;

&lt;p&gt;Separação entre operações de leitura e escrita, frequentemente combinado com EDA.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Saga Pattern
&lt;/h3&gt;

&lt;p&gt;Coordenação de transações distribuídas através de eventos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vantagens da EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Baixo Acoplamento&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Produtores e consumidores não se conhecem diretamente&lt;/li&gt;
&lt;li&gt;Facilita manutenção e evolução independente dos componentes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Alta Escalabilidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Processamento assíncrono permite melhor utilização de recursos&lt;/li&gt;
&lt;li&gt;Facilita escalonamento horizontal&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Flexibilidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Novos consumidores podem ser adicionados sem modificar produtores&lt;/li&gt;
&lt;li&gt;Suporte a múltiplos consumidores para o mesmo evento&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Resilência&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Falhas em um componente não afetam diretamente outros&lt;/li&gt;
&lt;li&gt;Possibilidade de reprocessamento de eventos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Auditoria e Rastreabilidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Histórico completo de mudanças de estado&lt;/li&gt;
&lt;li&gt;Facilita debugging e análise de comportamento&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Desvantagens e Desafios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Complexidade&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Debugging mais difícil devido à natureza assíncrona&lt;/li&gt;
&lt;li&gt;Rastreamento de fluxos pode ser complexo&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Eventual Consistency&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sistema pode estar temporariamente inconsistente&lt;/li&gt;
&lt;li&gt;Requer design cuidadoso para lidar com estados intermediários&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Gerenciamento de Ordem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eventos podem chegar fora de ordem&lt;/li&gt;
&lt;li&gt;Necessário estratégias para garantir processamento correto&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Latência de Processamento&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Processamento assíncrono pode introduzir delays&lt;/li&gt;
&lt;li&gt;Não adequado para operações que requerem resposta imediata&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tecnologias Populares
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Message Brokers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache Kafka&lt;/strong&gt;: Plataforma de streaming distribuída&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RabbitMQ&lt;/strong&gt;: Message broker tradicional com suporte a múltiplos protocolos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EventBridge&lt;/strong&gt;: Serviço de event bus serverless da AWS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Event Hubs&lt;/strong&gt;: Plataforma de streaming de dados da Microsoft&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Event Stores
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EventStore&lt;/strong&gt;: Banco de dados especializado em event sourcing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache Kafka&lt;/strong&gt;: Também pode servir como event store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;: Com padrões específicos para event sourcing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como você pode ver, a Event-Driven Architecture é um paradigma poderoso para construir sistemas distribuídos modernos. Oferece benefícios significativos em termos de escalabilidade, flexibilidade e manutenibilidade, mas requer cuidado especial no design e implementação.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
