en
· 4 min de leitura

Blue-green, canary e o rollback honesto

Estratégia de deploy só vale o rollback que ela realmente permite. A maioria dos times superestima o seu.

infra

Estratégia de deploy costuma ser explicada como um cardápio. Rolling update, blue-green, canary, escolha um. Eu acho esse enquadramento invertido. A estratégia não é o ponto. O ponto é o que você consegue fazer quando a versão nova é ruim, com que velocidade e com quanto dano nos dados. Escolha o rollback primeiro, e a estratégia sai como consequência.

O que cada estratégia realmente te dá

Rolling update substitui as instâncias uma de cada vez. É barato e é o default em quase todo lugar. O rollback é outro rolling update no sentido contrário, que demora o mesmo tanto que o deploy. Nessa janela, alguns usuários caem na versão ruim. Para um serviço com poucas instâncias e startup rápido, tudo bem. Para um serviço que sobe devagar com trinta instâncias, um deploy ruim significa um quarto de hora ruim.

Blue-green mantém dois ambientes completos e alterna o tráfego entre eles no load balancer ou no DNS. O rollback é a alternância ao contrário, e leva segundos. O custo é o dobro de computação durante a transição e, mais importante, um banco compartilhado com o qual os dois ambientes precisam concordar. Blue-green resolve o rollback de código lindamente e não faz absolutamente nada pelo rollback de dados.

Canary manda uma fatia pequena do tráfego, digamos de um a cinco por cento, para a versão nova, observa taxa de erro e latência por um período fixo e depois amplia. O rollback durante a fase de canary afeta só a fatia do canary. É a estratégia que transforma o deploy num experimento com raio de explosão que você escolheu. Exige que as suas métricas possam ser separadas por versão, o que é um problema de tag, não de plataforma.

O rollback desonesto

É aqui que a maioria dos planos de deploy desmorona. As três estratégias voltam código. Nenhuma volta estado. Se a versão nova rodou uma migration que removeu uma coluna, a versão velha vai quebrar na subida. Se a versão nova escreveu linhas num formato novo, a versão velha vai ler errado. Se a versão nova publicou eventos com schema novo, os consumers velhos já rejeitaram ou, pior, processaram errado.

O rollback honesto é aquele em que você já perguntou: o que a versão nova mudou que a versão velha não entende? Se a resposta é 'nada', você pode voltar com qualquer estratégia. Se a resposta é 'o schema', você não pode voltar de jeito nenhum, por mais verde que seja o seu azul.

Então a disciplina é: mudanças de schema são aditivas e saem sozinhas; o código que usa elas sai numa release seguinte; a limpeza que remove colunas velhas sai numa terceira. Cada release dessa cadeia é reversível individualmente. Parece lento. É o único jeito que eu conheço de manter 'a gente consegue fazer rollback' verdadeiro.

O que eu recomendo para um time pequeno

Para a maioria dos produtos com tráfego modesto, recomendo deploy rolling com health check travando cada instância, mais um canary manual para as releases arriscadas. O canary manual não é nada além de publicar em uma instância, ou uma região, ou um tenant, e observar por quinze minutos antes de continuar. Não precisa de service mesh. Precisa de um label de versão nas métricas e de uma pessoa disposta a esperar.

Blue-green paga o próprio custo quando o startup é lento, quando a release é grande ou quando o negócio não tolera nem um minuto de versões misturadas. Canary completo com análise automática paga o próprio custo quando os deploys são frequentes demais para um humano observar cada um.

O checklist antes de toda release

Duas versões podem rodar ao mesmo tempo no mesmo banco? Toda migration dessa release é retrocompatível com o código anterior? Se a gente reverter em dez minutos, que dados terão sido escritos num formato que o código velho não lê? Existe uma métrica, separada por versão, que vai dizer em cinco minutos que a versão nova é pior?

Se qualquer resposta é 'não' ou 'não temos certeza', a estratégia não importa. Você não vai fazer rollback. Vai seguir em frente com um hotfix, sob pressão, e deveria planejar a release como se isso fosse verdade, porque é.