Os Padrões dos Gigantes da Web - Deploy Contínuo

Sabemos que os Gigantes da Web (Google, Amazon, Netflix, Yahoo, etc.) costumam melhorar os seus produtos de maneira permanente respeitando assim a máxima "Release early, release often". Como é possível que eles entreguem melhorias tão rapidamente, se em algumas equipes de desenvolvimento qualquer mudança pode demorar semanas para chegar à produção?

Na maior parte das vezes, eles têm um processo de Deploy Contínuo ("Continuous Deploy") que segue uma dessas duas possibilidades:

  • totalmente automatizado: uma mudança no código é automaticamente verificada e, se tudo estiver certo, a aplicação vai para produção;

  • semi-automatizado: a ideia é ser capaz de empurrar para produção a última versão estável do aplicativo em qualquer momento apenas apertando um botão. Nesse caso, chamamos de "one-click-deployment".

Obviamente, a aplicação desses padrões tem alguns requisitos, mas antes de chegar lá vamos explicitar as vantagens do Deploy Contínuo.

Melhorar a sua velocidade de reação

A primeira motivação da Deploy Contínuo é de melhorar o Time To Market (tempo para entregar um produto), mas também de aproveitar dessa agilidade para testar algumas hipóteses, e por fim melhorar o produto.

No exemplo de um time que coloca novas versões em produção sempre no primeiro dia do mês (o que já seria bem freqüente na maioria das empresas):

  • Eu tenho uma boa ideia para uma nova funcionalidade no primeiro dia do mês;

  • Se "tivermos sorte", os desenvolvedores serão capazes de implementar essa funcionalidade dentro dos próximos trinta dias;

  • Colocamos essa boa ideia em produção, como planejado no plano de entrega mensal no primeiro dia do próximo mês;

  • Durante um mês, coletamos os dados de utilização dessa nova funcionalidade e entendemos o que temos que melhorar nessa primeira versão;

  • Temos que esperar novamente um mês para colocar em produção uma versão melhorada dessa funcionalidade.

No fim deste exemplo (não é exagero, acontece na realidade) serão três meses entre a ideia e a funcionalidade estável em produção.

Logo, não é o tempo de desenvolvimento que atrapalha a agilidade mas é o processo e o plano de entrega. O Deploy Contínuo permite melhorar o Time To Market e também acelerar os ciclos de melhoria do produto.

Desta forma, chegamos no ciclo bem conhecido do Lean Startup:

Figura 1: Lean StartupFigura 1: Lean Startup

Algumas definições

Sempre confundimos os conceitos de "Entrega Contínua" e de "Deploy Contínuo". Para alinhar, aqui estão as nossas definições dependendo do que acontece quando um desenvolvedor faz um commit:

  • Integração Contínua: Compilado, testado, colocado no um ambiente de integração;

  • Entrega Contínua: Compilado, testado, empurrado para o time seguinte (que pode ser Testes, Qualificação, Operações);

  • Deploy Contínuo: Compilado, testado, colocado em produção.

A ideia aqui não é dizer que a Entrega Contínua e a Integração Contínua não importam mas, ao contrário, estes são passos essenciais. O Deploy Contínuo é a extensão natural da Entrega Contínua, que é a extensão natural da Integração Contínua.

Entregar todo dia não atrapalha a qualidade

Uma das críticas comuns quando falamos sobre o Deploy Contínuo é a falta de qualidade que pode surgir da precipitação de entregar em produção: Não há um risco de entregar algo errado, de entregar código com bugs?

Só é possível tirar vantagem do Deploy Contínuo, se houver confiança absoluta no código existente, em qualquer instante. Para isso, precisamos ter uma boa cobertura de testes. Fora dos testes unitários, vamos precisar também de outros tipos de teste automatizados:

  • Testes de Integração: Fitnesse, GreenPepper, Concordion, etc;

  • Testes de Interface: Selenium;

  • Testes de Performance: Gatling, OpenSTA, jMeter, etc.

A automatização desses testes pode custar algum tempo, mas se o objetivo é executar várias vezes no dia (IMVU executa 1 milhão de testes /dia), o retorno sobre o investimento é bem rápido. Algumas empresas, como a Etsy, criam e compartilham ferramentas que eles usam em seus testes automatizados.

De qualquer maneira, quando fazemos um deploy todo dia, as mudanças são menores do que quando fazemos um deploy por mês. Assim, se algo quebra, o Time-To-Repair (tempo para reparo) será menor, conforme ilustrado:

Change Size Vs. Change FrequencyFigura 2: Change Size Vs. Change Frequency

As grandes mudanças trazem grandes problemas. As pequenas mudanças trazem pequenos problemas.

A Etsy nos deu uma boa idéia da confiança que eles tem no código, e a sua capacidade de recuperar rapidamente. Eles nem tem mecanismos de rollback: "We don’t roll back, we fix the code" ("Nós não fazemos rollbacks, nós consertamos"). De acordo com um desenvolvedor, o maior tempo para consertar um erro crítico é de quatro minutos.

Eles já fazem Deploy Contínuo

Vários Gigantes da Web já implementaram o Deploy Contínuo com sucesso:

  • O Facebook, que costuma automatizar todos os testes, faz dois deploys por dia, usando a estratégia do Rolling Deploy. Dois deploys por dia não parece algo tão impressionante, mas trata-se de um aplicativo de 1.5 GB distribuido usando o protocolo Torrent.

  • O FlickR usa o Feature Flipping para evitar trabalhar com branching, e faz mais de dez deploys por dia.

  • A Etsy investiu muito nos seus testes automatizados e nas suas ferramentas. Hoje, eles fazem mais de 25 deploys por dia.

  • O IMVU (site de jogos sociais e avatars 3D) executa mais de 1 milhão de testes e 50 deploys cada dia.

E na minha empresa?

Primeiro faça uma estimativa (ou medição) do tempo que seu time precisa para entregar uma linha de código em produção com o processo que vocês têm hoje.

Ter uma Integração Contínua bem testada

Montar um servidor de Integração Contínua, que é o primeiro passo para o Deploy Contínuo.

Antes de continuar, é fundamental certificar-se que os testes existentes cobrem a maior parte do aplicativo. Se algumas empresas não hesitam em criar os seus próprios frameworks de testes (Netflix criou o projeto "Chaos Monkey" que desliga os servidores aleatoriamente), é perfeitamente possível usar os frameworks existentes, como JUnit, Gatling, Fitnesse, etc. Para diminuir o tempo de execução dos testes, a IMVU os distribui em mais de 30 máquinas. Outras empresas preferem usar os serviços de Nuvem, como Amazon Web Services, para instanciar os ambientes de Teste na hora e paralelizar a execução dos testes.

Automatizar para chegar até a Deploy Contínuo

Quando a integração contínua já estiver compilando e testando suficientemente os artefatos, ela já poderá ser usada para entregar os artefatos para o time que vai subir o aplicativo nos diferentes ambientes. Nesse estágio, já estamos na Entrega Contínua.

Agora, o time que cuida dos deploys precisa melhorar as construções e adicionar as tarefas de deploy. Esse passo requer que as tarefas de configuração dos ambientes, de deploy dos artefatos e de migração dos esquemas de banco de dados (caso existam) já estejam automatizadas.

É preciso dar atenção especial aos scripts de deploy, já que eles são código, e devem respeitar os critérios de qualidade, sendo versionados num repositório, com testes, etc.

Forçar até o Deploy Contínuo

Uma solução mais radical, porém bem interessante, é forçar o ritmo da entrega. Por exemplo, trocar uma entrega mensal para uma semanal. Isso irá expor os problemas que atrapalham o processo de Deploy, permitindo planejar ações de melhoria.

Padrões relacionados

Tem alguns padrões de arquitetura bem úteis para implementar o Deploy Contínuo:

  • Zero Downtime Deployment (Deploy sem interupção): se uma interrupção do serviço por hora não é um problema quando é mensal, pode virar uma catástrofe quando entregamos semanalmente ou diariamente.
  • Feature Flipping (Troca de funcionalidade): uma entrega normal pode resultar na entrega de funcionalidades não finalizadas ou com erros. Nesse caso, precisamos ser capazes de desativar na hora ou antecipadamente as funcionalidades que podem trazer problemas.

Fontes: