Deployments Canary com Kotlin: lançamento contínuo 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

Por que o deploy comum é sempre uma loteria?

\n

Todo desenvolvedor já passou pelo momento da verdade pelo menos uma vez na vida: você aperta o botão "Deploy" e o coração vai à boca. E se a nova versão derrubar o banco? E se os usuários virem o erro 500 em vez da página inicial?

\n

O deploy comum é como pular de paraquedas sem reserva. Ou tudo funciona perfeitamente, ou você passa a noite analisando logs, tentando entender o que deu errado. Mas existe uma maneira de tornar esse processo seguro — canary deployments (deploy canário).

\n

Neste artigo, vamos explorar como implementar um canary deployment em Kotlin usando Ktor e um balanceador simples. Você aprenderá a entregar código novo primeiro para 5% dos usuários e, em seguida, aumentar gradualmente o tráfego. E sim, escreveremos código que realmente funciona.

\n\n

O que é Canary deployment e por que você precisa dele?

\n

Imagine que você é o capitão de um navio. Em vez de navegar diretamente pelos recifes, você envia um pequeno barco (canário) na frente. Se ele passar, toda a frota navega. Se ele afundar, você perde apenas um barco.

\n

No mundo da TI, isso funciona assim: você implanta a nova versão do serviço primeiro para um pequeno grupo de usuários. Se as métricas estiverem boas, o tráfego aumenta. Se não, você reverte em segundos.

\n

As vantagens são óbvias:

\n
    \n
  • Minimização de riscos — os bugs afetam apenas 1-5% do público.
  • \n
  • Feedback rápido — você vê os erros antes que se tornem uma catástrofe.
  • \n
  • Teste A/B — é possível comparar o desempenho das versões antiga e nova.
  • \n
  • Zero downtime — os usuários não percebem a troca.
  • \n
\n

Mas há um porém: é preciso saber gerenciar o tráfego, monitorar métricas e automatizar o processo. Kotlin, com sua concisão e corrotinas, é excelente para essa tarefa.

\n\n

Arquitetura do Canary deployment em Kotlin

\n

Vamos construir uma arquitetura simples, mas funcional. Teremos:

\n
    \n
  • Balanceador — decide qual porcentagem das requisições vai para a versão antiga (stable) e qual para a nova (canary).
  • \n
  • Duas instâncias do serviço — stable e canary, ambas escritas em Kotlin com Ktor.
  • \n
  • Monitoramento — contadores de erros e tempo de resposta.
  • \n
\n

O balanceador tomará a decisão com base no cabeçalho X-Canary ou em uma distribuição aleatória. Seguiremos o segundo caminho — é mais próximo da realidade.

\n\n

Escrevendo o código: balanceador em Kotlin

\n

Começaremos pelo balanceador. Ele receberá as requisições e as encaminhará para um dos dois serviços. Para simplificar, usaremos o cliente HTTP embutido do Ktor.

\n\n
import io.ktor.client.*\nimport io.ktor.client.engine.cio.*\nimport io.ktor.client.request.*\nimport io.ktor.client.statement.*\nimport io.ktor.server.application.*\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.response.*\nimport io.ktor.server.routing.*\nimport kotlinx.coroutines.runBlocking\nimport kotlin.random.Random\n\n// Configuração\nconst val STABLE_URL = "http://localhost:8081"\nconst val CANARY_URL = "http://localhost:8082"\nvar canaryPercent = 5 // Começamos com 5% do tráfego\n\nfun main() {\n    val client = HttpClient(CIO)\n\n    embeddedServer(Netty, port = 8080) {\n        routing {\n            get("/api/data") {\n                val useCanary = Random.nextInt(100) < canaryPercent\n                val targetUrl = if (useCanary) CANARY_URL else STABLE_URL\n\n                val response = runBlocking {\n                    client.get("$targetUrl/api/data")\n                }\n\n                call.respondText(\n                    response.bodyAsText(),\n                    contentType = response.contentType()\n                )\n            }\n\n            // Endpoint para alterar a porcentagem do canário\n            get("/canary/set/{perc")                

Blogs

Book Recommendations