<?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>Forem: Kaue Campos</title>
    <description>The latest articles on Forem by Kaue Campos (@sh4rkzy).</description>
    <link>https://forem.com/sh4rkzy</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%2F1933929%2F7c154c92-bc0c-4f5d-99bb-125db3bc2da8.jpeg</url>
      <title>Forem: Kaue Campos</title>
      <link>https://forem.com/sh4rkzy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sh4rkzy"/>
    <language>en</language>
    <item>
      <title>Do Monólito ao Supergraph: Como o GraphQL Federation Escala Microservices</title>
      <dc:creator>Kaue Campos</dc:creator>
      <pubDate>Wed, 18 Feb 2026 14:02:15 +0000</pubDate>
      <link>https://forem.com/sh4rkzy/do-monolito-ao-supergraph-como-o-graphql-federation-escala-microservices-1l38</link>
      <guid>https://forem.com/sh4rkzy/do-monolito-ao-supergraph-como-o-graphql-federation-escala-microservices-1l38</guid>
      <description>&lt;p&gt;Recentemente, um novo desafio profissional me tirou da zona de conforto e me colocou diante de um problema que não era apenas técnico, mas estrutural: como escalar uma API GraphQL em um ambiente com múltiplos times, múltiplos domínios e deploys independentes.&lt;/p&gt;

&lt;p&gt;Eu já conhecia o &lt;strong&gt;GraphQL&lt;/strong&gt;, mas foi ao mergulhar em &lt;strong&gt;Federation&lt;/strong&gt; que comecei a enxergar a diferença entre resolver o problema do cliente e resolver o problema da organização.&lt;/p&gt;

&lt;p&gt;Este artigo não é sobre como usar GraphQL. É sobre o que acontece quando ele cresce demais.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é GraphQL (e por que ele foi revolucionário)
&lt;/h1&gt;

&lt;p&gt;Criado pelo Facebook (hoje Meta) em 2015, o &lt;strong&gt;GraphQL&lt;/strong&gt; surgiu para resolver limitações práticas das APIs REST:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overfetching&lt;/li&gt;
&lt;li&gt;Underfetching&lt;/li&gt;
&lt;li&gt;Multiplicidade de endpoints&lt;/li&gt;
&lt;li&gt;Evolução difícil de contrato&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O diferencial do GraphQL é simples e poderoso: o cliente define exatamente os dados que precisa, em uma única requisição, com um schema fortemente tipado servindo como contrato.&lt;/p&gt;

&lt;p&gt;Isso trouxe ganhos reais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redução de payload&lt;/li&gt;
&lt;li&gt;Flexibilidade para múltiplos clientes (web, mobile, IoT)&lt;/li&gt;
&lt;li&gt;Evolução incremental de schema&lt;/li&gt;
&lt;li&gt;Documentação automática via introspection&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%2F45lkw17k856953fm15zx.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%2F45lkw17k856953fm15zx.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em projetos pequenos ou médios, um único servidor GraphQL central funciona muito bem.&lt;/p&gt;

&lt;p&gt;O problema começa quando a empresa cresce.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Limite do GraphQL Centralizado
&lt;/h2&gt;

&lt;p&gt;GraphQL resolve o problema da comunicação cliente-servidor, mas ele não resolve automaticamente o problema organizacional.&lt;/p&gt;

&lt;p&gt;Quando múltiplos times começam a alterar o mesmo schema, surgem sintomas claros.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Gargalo de Deploy
&lt;/h3&gt;

&lt;p&gt;Em um schema centralizado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Todos os domínios vivem no mesmo repositório.&lt;/li&gt;
&lt;li&gt;Alterações geram conflitos frequentes.&lt;/li&gt;
&lt;li&gt;Pull requests começam a se bloquear.&lt;/li&gt;
&lt;li&gt;O pipeline de CI/CD vira gargalo compartilhado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O efeito colateral é sutil, mas perigoso:&lt;/p&gt;

&lt;p&gt;times passam a coordenar releases por causa da API.&lt;/p&gt;

&lt;p&gt;Isso reduz autonomia e desacelera evolução.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Propriedade Indefinida do Schema
&lt;/h3&gt;

&lt;p&gt;Quem é dono do tipo &lt;code&gt;User&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se Pagamentos adiciona um campo que quebra Usuários, quem corrige?&lt;/li&gt;
&lt;li&gt;Se Crédito precisa alterar uma entidade base, precisa negociar com quantos times?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sem ownership claro, o schema vira um território compartilhado sem fronteiras.&lt;/p&gt;

&lt;p&gt;E territórios sem fronteiras geram conflitos.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Monólito de API (Mesmo com Microserviços)
&lt;/h3&gt;

&lt;p&gt;Esse é um erro comum.&lt;/p&gt;

&lt;p&gt;Você tem microserviços separados, mas cria um único servidor GraphQL que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conhece todos os bancos&lt;/li&gt;
&lt;li&gt;Orquestra regras de negócio cruzadas&lt;/li&gt;
&lt;li&gt;Acessa múltiplos domínios diretamente&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na prática, você criou um monólito de API em cima de microserviços.&lt;/p&gt;

&lt;p&gt;A complexidade volta a se concentrar em um único ponto.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Problemas de Versionamento de Schema
&lt;/h3&gt;

&lt;p&gt;Em um schema único:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking changes exigem coordenação global.&lt;/li&gt;
&lt;li&gt;Depreciações demoram meses.&lt;/li&gt;
&lt;li&gt;Não existe versionamento isolado por domínio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qualquer alteração estrutural passa a ser um evento organizacional.&lt;/p&gt;

&lt;p&gt;Isso não escala.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é GraphQL Federation?
&lt;/h2&gt;

&lt;p&gt;A Federation foi popularizada pelo ecossistema Apollo como uma forma de dividir o schema em partes independentes chamadas subgraphs.&lt;/p&gt;

&lt;p&gt;Cada subgraph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Possui seu próprio schema&lt;/li&gt;
&lt;li&gt;Possui seu próprio ciclo de deploy&lt;/li&gt;
&lt;li&gt;É responsável pelo seu domínio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O gateway compõe esses schemas em um supergraph único.&lt;/p&gt;

&lt;p&gt;O ponto central da Federation não é dividir arquivos.&lt;/p&gt;

&lt;p&gt;É distribuir responsabilidade.&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%2Fa3eb1qcc1crh6puukphm.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%2Fa3eb1qcc1crh6puukphm.png" alt=" " width="800" height="882"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine três domínios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contas&lt;/li&gt;
&lt;li&gt;Transações&lt;/li&gt;
&lt;li&gt;Crédito&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O serviço de Contas define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&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="n"&gt;id&lt;/span&gt;&lt;span class="err"&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;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&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;O serviço de Crédito pode estender esse tipo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;extend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&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="n"&gt;id&lt;/span&gt;&lt;span class="err"&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;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&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="n"&gt;external&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;creditLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&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;O domínio de Crédito não precisa que Contas conheça seu modelo interno.&lt;br&gt;
A dependência é declarativa e contratual.&lt;/p&gt;

&lt;p&gt;Isso reduz acoplamento estrutural entre domínios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gateway vs Router: Uma Distinção Importante
&lt;/h2&gt;

&lt;p&gt;Quando falamos em Federation, precisamos diferenciar duas implementações principais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apollo Gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implementado em Node.js&lt;/li&gt;
&lt;li&gt;Baseado em JavaScript&lt;/li&gt;
&lt;li&gt;Primeira geração de runtime federado&lt;/li&gt;
&lt;li&gt;Alta flexibilidade e fácil customização&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ele foi essencial para popularizar Federation.&lt;/p&gt;

&lt;p&gt;Porém, possui limitações naturais do ambiente Node:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event loop único&lt;/li&gt;
&lt;li&gt;Garbage collection impactando latência&lt;/li&gt;
&lt;li&gt;Maior consumo de memória sob alta carga&lt;/li&gt;
&lt;li&gt;Performance limitada em cenários de alta concorrência&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para cargas moderadas, funciona bem.&lt;/p&gt;

&lt;p&gt;Para escala massiva, começa a mostrar limites.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apollo Router
&lt;/h3&gt;

&lt;p&gt;O Apollo Router é uma reescrita completa em Rust.&lt;/p&gt;

&lt;p&gt;Características técnicas relevantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compilado (não interpretado)&lt;/li&gt;
&lt;li&gt;Sem garbage collector&lt;/li&gt;
&lt;li&gt;Controle fino de concorrência&lt;/li&gt;
&lt;li&gt;Arquitetura orientada a streaming&lt;/li&gt;
&lt;li&gt;Melhor paralelização de chamadas a subgraphs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na prática, isso significa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latência menor (principalmente P95/P99)&lt;/li&gt;
&lt;li&gt;Melhor throughput&lt;/li&gt;
&lt;li&gt;Uso mais eficiente de CPU&lt;/li&gt;
&lt;li&gt;Menor consumo de memória&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em arquiteturas distribuídas, o gateway é o ponto mais crítico do sistema.&lt;/p&gt;

&lt;p&gt;Ele está em todas as requisições.&lt;/p&gt;

&lt;p&gt;Se ele degrada, todo o sistema degrada.&lt;/p&gt;

&lt;p&gt;Por isso o Router se tornou a escolha padrão em ambientes de alta escala.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Planning: O Cérebro do Supergraph
&lt;/h3&gt;

&lt;p&gt;O gateway não apenas encaminha requisições.&lt;/p&gt;

&lt;p&gt;Ele constrói um plano de execução (query plan):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analisa a query do cliente&lt;/li&gt;
&lt;li&gt;Determina quais campos pertencem a cada subgraph&lt;/li&gt;
&lt;li&gt;Resolve dependências entre entidades&lt;/li&gt;
&lt;li&gt;Executa chamadas em paralelo sempre que possível&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse planejamento é essencial para minimizar latência e reduzir chamadas desnecessárias entre serviços.&lt;/p&gt;

&lt;p&gt;A eficiência do query planner é um dos fatores que diferencia implementações de gateway.&lt;/p&gt;




&lt;h3&gt;
  
  
  Acoplamento Entre Domínios
&lt;/h3&gt;

&lt;p&gt;Sem Federation, domínios começam a vazar entre si:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crédito acessa diretamente o banco de Usuário&lt;/li&gt;
&lt;li&gt;Pagamentos depende de estrutura interna de Contas&lt;/li&gt;
&lt;li&gt;Resolvers centrais começam a concentrar lógica cruzada&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso gera:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependências circulares&lt;/li&gt;
&lt;li&gt;Dificuldade de refatoração&lt;/li&gt;
&lt;li&gt;Aumento da complexidade cognitiva&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Federation força disciplina arquitetural:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cada domínio é responsável por seus dados&lt;/li&gt;
&lt;li&gt;Extensões são explícitas&lt;/li&gt;
&lt;li&gt;O contrato é validado na composição do supergraph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O acoplamento deixa de ser implícito e passa a ser formalizado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Em resumo:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL resolve o problema do cliente.&lt;/li&gt;
&lt;li&gt;Federation resolve o problema da organização.&lt;/li&gt;
&lt;li&gt;E o Router resolve o problema da escala.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando a API começa a refletir a estrutura da empresa, a arquitetura precisa evoluir junto. Federation não é apenas uma técnica de composição de schema. É um modelo arquitetural que permite autonomia, governança e escalabilidade organizacional.&lt;/p&gt;

&lt;p&gt;O supergraph não é apenas uma evolução técnica, ele é um reflexo da maturidade do sistema e da organização que o construiu.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>microservices</category>
      <category>api</category>
      <category>node</category>
    </item>
    <item>
      <title>Como Melhorar o Desempenho de Aplicações Node.js com Clusterização</title>
      <dc:creator>Kaue Campos</dc:creator>
      <pubDate>Thu, 31 Oct 2024 17:48:49 +0000</pubDate>
      <link>https://forem.com/sh4rkzy/como-melhorar-o-desempenho-de-aplicacoes-nodejs-com-clusterizacao-lj4</link>
      <guid>https://forem.com/sh4rkzy/como-melhorar-o-desempenho-de-aplicacoes-nodejs-com-clusterizacao-lj4</guid>
      <description>&lt;p&gt;Um dos grandes dilemas para nós, desenvolvedores, é como oferecer a melhor performance para o usuário final. Queremos que nossos sistemas sejam ágeis, eficientes e menos propensos a falhas. Mas, em meio ao desenvolvimento, nem sempre percebemos algumas estratégias que podem fazer uma grande diferença nesse quesito.&lt;/p&gt;

&lt;p&gt;Imagine o seguinte cenário: você tem uma aplicação hospedada em um cloud provider, como a AWS, utilizando uma instância EC2 para rodar uma API em Node.js. Tudo está funcionando bem, mas, com o aumento da carga, o servidor começa a apresentar limitações. Ele só consegue processar um certo número de requisições simultâneas, gerando lentidão e até falhas em horários de pico. Isso acontece porque, por padrão, o Node.js opera em um único thread, usando apenas um núcleo de CPU.&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%2Fj6vg58azjshpnfse3uzk.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%2Fj6vg58azjshpnfse3uzk.png" alt="Cenario for ec2" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui, muitos desenvolvedores podem pensar em escalar a aplicação horizontalmente, criando novas instâncias de servidor. No entanto, antes disso, uma alternativa poderosa e eficiente está à nossa disposição: a clusterização de processos em Node.js. Com essa técnica, conseguimos aproveitar ao máximo os recursos de CPU do servidor, criando um ambiente mais robusto e escalável, tudo sem precisar criar novas instâncias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tá, mas como funciona a clusterização afinal?
&lt;/h2&gt;

&lt;p&gt;A clusterização é uma técnica que permite executar várias cópias de uma aplicação Node.js (chamadas de workers) em paralelo, dentro do mesmo servidor. Como o Node.js é, por natureza, um ambiente de execução single-threaded, ele usa apenas um núcleo de CPU por vez. Isso limita a capacidade de processamento, principalmente em servidores multicore, onde recursos estão ociosos enquanto a aplicação utiliza apenas um núcleo.&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%2F8i0cplcftz3rall8w14d.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%2F8i0cplcftz3rall8w14d.png" alt="Clusters nodejs" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Através da clusterização, podemos criar múltiplos workers, cada um rodando uma instância separada da aplicação. Estes processos são gerenciados por um processo principal (ou mestre), que distribui as requisições entre os workers disponíveis. Cada worker pode ser alocado em um núcleo de CPU diferente, permitindo que a aplicação use todos os núcleos da máquina, distribuindo a carga de trabalho e aumentando significativamente o desempenho.&lt;/p&gt;

&lt;p&gt;Imagine que você tenha um servidor com 4 núcleos de CPU e que, sem clusterização, sua aplicação usa apenas um deles. Ao clusterizar a aplicação, podemos criar 4 workers, cada um em um núcleo. Isso quer dizer que, em vez de processar, por exemplo, 100 requisições por segundo, ela poderia processar até 400, com uma carga mais bem distribuída e menor tempo de resposta.&lt;/p&gt;

&lt;p&gt;Outro benefício importante é a resiliência. Com vários processos rodando, se um worker falha, o processo principal pode reiniciar apenas o worker afetado, sem derrubar toda a aplicação. Isso resulta em uma aplicação mais estável e menos sujeita a períodos de inatividade. Além disso, como todos os workers compartilham o mesmo servidor, eles acessam os mesmos recursos (como a memória e o sistema de arquivos), o que reduz a necessidade de escalonamento horizontal imediato (como a criação de novas instâncias de servidor) e diminui os custos.&lt;/p&gt;

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

&lt;p&gt;A clusterização de processos em Node.js é uma estratégia poderosa que pode transformar o desempenho das suas aplicações, especialmente em ambientes de produção onde a carga de trabalho pode ser imprevisível. Ao implementar múltiplos workers, você não só melhora a capacidade de resposta e a escalabilidade da sua aplicação, mas também a torna mais resiliente a falhas. Isso significa que sua aplicação pode aproveitar ao máximo os recursos de CPU disponíveis, permitindo que atenda a um número maior de requisições simultâneas de forma eficiente.&lt;/p&gt;

&lt;p&gt;Se você está curioso para aprender mais sobre como implementar a clusterização em suas aplicações Node.js, eu recomendo dar uma olhada neste artigo que explico sobre &lt;a href="https://dev.to/sh4rkzy/criando-clusterizacao-em-aplicacoes-nodejs-56df"&gt;Criando Clusterização em Aplicações Node.js&lt;/a&gt;. É uma excelente maneira de começar a otimizar sua aplicação e proporcionar uma experiência ainda melhor para suas apis!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Criando Clusterização em Aplicações Node.js</title>
      <dc:creator>Kaue Campos</dc:creator>
      <pubDate>Thu, 31 Oct 2024 17:39:18 +0000</pubDate>
      <link>https://forem.com/sh4rkzy/criando-clusterizacao-em-aplicacoes-nodejs-56df</link>
      <guid>https://forem.com/sh4rkzy/criando-clusterizacao-em-aplicacoes-nodejs-56df</guid>
      <description>&lt;p&gt;O Node.js é uma plataforma popular para desenvolver aplicações escaláveis, mas sua arquitetura de thread única pode se tornar um gargalo em situações de alta carga. Para aproveitar ao máximo o poder do Node.js, a clusterização é uma técnica eficaz que permite utilizar múltiplos núcleos de CPU, melhorando o desempenho e a capacidade de resposta da sua aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pré-requisitos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js instalado na sua máquina. Você pode baixar a versão mais recente em &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;nodejs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Familiaridade básica com JavaScript e Node.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Passo 1: Criar um Novo Projeto Node.js
&lt;/h3&gt;

&lt;p&gt;Primeiro, crie um novo diretório para o seu projeto e inicie um novo projeto Node.js:&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="nb"&gt;mkdir &lt;/span&gt;node-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;node-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 2: Instalar Dependências
&lt;/h3&gt;

&lt;p&gt;Para este tutorial, você precisará apenas do próprio Node.js, mas vamos usar o express para criar um servidor HTTP simples. Instale o express com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 3: Criar o Servidor com Clusterização
&lt;/h3&gt;

&lt;p&gt;Crie um arquivo chamado &lt;code&gt;server.js&lt;/code&gt; e adicione o seguinte código:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&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;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&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;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;numCPUs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware para simular processamento intenso&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Soma: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Processado pelo Worker: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Lógica de clusterização&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isMaster&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Master &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is running`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Cria um worker para cada núcleo de CPU&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numCPUs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exit&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="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; morreu`&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Cada worker escuta na mesma porta&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; started`&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;p&gt;&lt;em&gt;A configuração do cluster deve ser feita de acordo com a quantidade de CPUs disponíveis em sua máquina ou servidor. Por exemplo, se o seu servidor possui 6 CPUs, é ideal criar 6 workers para aproveitar ao máximo os recursos disponíveis. Utilizar mais workers do que núcleos de CPU pode levar a uma sobrecarga e diminuir o desempenho, enquanto usar menos workers pode resultar em subutilização dos recursos. É recomendável testar diferentes configurações para encontrar o equilíbrio ideal entre desempenho e utilização de recursos.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 4: Executar a Aplicação
&lt;/h3&gt;

&lt;p&gt;Agora você pode executar sua aplicação. Use o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso siga o exemplo voce verá em seu terminal algo semelheate a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Master 12345 is running
Worker 12346 started
Worker 12347 started
Worker 12348 started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 5: Teste a Aplicação
&lt;/h3&gt;

&lt;p&gt;Para testar a rota &lt;code&gt;/&lt;/code&gt; do seu servidor local utilizando &lt;code&gt;curl&lt;/code&gt;, você pode usar o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao executar o comando acima no terminal, você deve receber uma resposta similar a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Soma: 49999995000000, Processado pelo Worker: 12348
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
      <category>typescript</category>
      <category>api</category>
    </item>
  </channel>
</rss>
