Canary deploy em JavaScript: lançamentos seguros sem medo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Deploy Canary com JavaScript: como lançar atualizações sem medo de quebrar tudo

\n\n

Você já lançou um novo recurso à meia-noite, rezando para o servidor não cair? Ou acordou com uma notificação "erro 500 em todas as páginas"? Familiar, né? Lançamentos são sempre estressantes. Mas existe uma maneira de torná-los tranquilos como uma manhã de fim de semana: Canary deployments (implantações canárias).

\n\n

O nome vem de uma antiga prática de mineradores — levar canários para a mina. Se o pássaro silenciasse, significava que o ar estava envenenado e era preciso sair correndo. No mundo do desenvolvimento JavaScript, o princípio é o mesmo: primeiro, enviamos uma pequena porcentagem de usuários para a nova versão, monitoramos a "saúde" do sistema e só então fazemos o lançamento completo.

\n\n

Neste artigo, vamos abordar como implementar um canary deployment em JavaScript puro (e um pouco de Node.js). Sem ferramentas corporativas complexas — apenas código, lógica e bom senso.

\n\n

Por que canary, e não blue-green ou rolling update?

\n\n

Existem várias estratégias de deploy. Blue-green é quando você tem dois ambientes idênticos e simplesmente alterna o tráfego. Rolling update é a substituição gradual de pods no Kubernetes. Mas o canary tem um superpoder: um teste A/B real com usuários reais.

\n\n
    \n
  • Menos risco: se a nova versão "matar" o banco de dados, apenas 1% dos usuários será afetado, não 100%.
  • \n
  • Feedback rápido: você vê as métricas do novo código antes que ele chegue a todos.
  • \n
  • Rollback automático: se o erro aumentar, o canary é desligado automaticamente.
  • \n
\n\n

Arquitetura de canary deployment em JavaScript

\n\n

Imagine que temos uma aplicação Express que serve páginas HTML. Queremos lançar um novo layout para a página inicial. Em vez de alterar o roteador para todos, criaremos uma camada intermediária — um canary middleware.

\n\n

Componentes do sistema

\n
    \n
  • Feature flag — uma flag que ativa a nova versão para um grupo específico.
  • \n
  • Distribuidor de tráfego — a lógica que decide: entregar a versão antiga (v1) ou a nova (v2).
  • \n
  • Monitoramento — coleta de métricas (erros, latência, conversões).
  • \n
  • Rollback automático — se as métricas caírem abaixo do limite.
  • \n
\n\n

Exemplo simples com Node.js e Express

\n\n

Vamos começar com um servidor básico. Suponha que temos dois handlers: v1 (antigo) e v2 (novo).

\n\n
const express = require('express');\nconst app = express();\nconst PORT = 3000;\n\n// Versão antiga\napp.get('/api/v1/home', (req, res) => {\n  res.json({ version: 'v1', message: 'Bom e velho design' });\n});\n\n// Nova versão (canary)\napp.get('/api/v2/home', (req, res) => {\n  res.json({ version: 'v2', message: 'Design novo e brilhante!' });\n});\n\napp.listen(PORT, () => console.log(`Servidor rodando na porta ${PORT}`));\n
\n\n

Agora precisamos decidir para quem mostrar a v2. A maneira mais simples é uma seleção aleatória baseada no user ID.

\n\n

Distribuição de tráfego: aleatoriedade determinística

\n\n

Não queremos que o mesmo usuário fique pulando entre versões a cada requisição. Por isso, usamos um hash do user ID:

\n\n
function getCanaryGroup(userId, percentage = 5) {\n  // Hash simples: soma dos códigos dos caracteres\n  const hash = userId.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);\n  return (hash % 100) < percentage;\n}\n\n// Exemplo de uso\nconsole.log(getCanaryGroup('user_123')); // true ou false\n
\n\n

Agora, no middleware, verificamos se o usuário está no grupo canary:

\n\n
app.use('/api/home', (req, res, next) => {\n  const userId = req.headers['x-user-id'] || 'anonymous';\n  \n  if (getCanaryGroup(userId, 5)) { // 5% do tráfego\n    req.url = '/api/v2/home';\n  } else {\n                

Blogs

Book Recommendations