
Nossa reunião de junho em Teste na produção foi dedicada à engenharia do caos. A engenheira de software líder Norah Jones começou com a maneira como a Netflix conduz testes em produção.
“Engenharia do caos ... são experimentos em produção para encontrar vulnerabilidades em um sistema antes que eles tornem um serviço inadequado para os clientes. Na Netflix, nós os executamos usando uma ferramenta chamada ChAP ... [captura] de vulnerabilidades e nos permite implementar falhas em serviços e produção. Essas falhas confirmam as suposições sobre esses serviços antes de levar a interrupções completas. ”
Assista a uma apresentação (ou leia a transcrição) sobre como sua equipe ajuda os usuários - engenheiros da Netflix - a testarem com segurança na produção e identificarem ativamente as vulnerabilidades em seus sistemas.
Descriptografia
Estou muito feliz por estar aqui hoje.
A Netflix usa ativamente testes na produção. Fazemos isso através da engenharia do caos e renomeamos recentemente nossa equipe Engenharia de Resiliência [desenvolvimento sustentável] porque a engenharia do caos é uma maneira de alcançar a sustentabilidade geral. Estou prestes a falar sobre isso hoje.
Nosso objetivo é aumentar o tempo de atividade pesquisando proativamente as vulnerabilidades nos serviços. Fazemos isso através de experimentos em produção. A equipe está confiante de que uma determinada classe de vulnerabilidades e problemas pode ser detectada apenas no tráfego real.
Antes de tudo, você deve cuidar da segurança e do monitoramento; caso contrário, não poderá implantar testes normais na produção. Tais testes podem ser assustadores: se assustarem, você deve ouvir essa voz e descobrir o porquê. Talvez porque você não tenha um bom sistema de segurança. Ou porque não há um bom monitoramento. Em nossas ferramentas, realmente nos preocupamos com essas coisas.
Se formularmos a engenharia do caos em uma frase, essa é a disciplina dos experimentos em produção para encontrar vulnerabilidades no sistema antes que eles tornem o serviço inadequado para os clientes. Na Netflix, os executamos usando uma ferramenta chamada ChAP, que significa a Chaos Automation Platform (Chaos Automation Platform). O ChAP captura vulnerabilidades e permite que os usuários implementem falhas nos serviços e na produção. Essas falhas confirmam as suposições do usuário sobre esses serviços antes de levar a interrupções em grande escala.
Vou lhe dizer como a plataforma funciona em um nível alto. Este é um conjunto hipotético de dependências de microsserviço. Existe um certo proxy. Ele envia uma solicitação para o serviço A, que diverge sem ventilador para os serviços B, C e D, e ainda há um nível de persistência. O serviço D acessa o Cassandra e o serviço B acessa o cache.
Corro à frente e resumi tudo, porque a essência começa ainda mais. Queremos garantir que o serviço D seja robusto contra uma falha de cache. O usuário entra na interface ChAP e seleciona o serviço D como um serviço que observa falhas de cache e um serviço para falhas. O ChAP realmente clona o serviço B em duas cópias. Nós os usamos para controle em clusters experimentais: de alguma forma eles funcionam como testes A / B ou canários. Essas réplicas são muito menores que o serviço B. Enviamos apenas uma porcentagem muito, muito pequena de clientes para esses clusters porque, obviamente, não queremos uma falha completa. Calculamos esse percentual com base no número atual de usuários que usam o serviço no momento.
O ChAP instrui o sistema de failover a sinalizar solicitações que correspondem aos nossos critérios. Isso é feito adicionando informações aos cabeçalhos da solicitação. Dois conjuntos de tags são criados. No primeiro conjunto de instruções para falha e roteamento para a réplica de canário, e no segundo - apenas instruções para roteamento para o elemento de monitoramento.
Quando o cliente e o serviço RPC A recebem as instruções necessárias para rotear a solicitação, eles realmente direcionam o tráfego para o cluster de monitoramento ou cluster experimental. Em seguida, o sistema de implementação de falhas no nível RPC do cluster experimental vê que a solicitação está marcada para falha e retorna uma resposta com falha. Como antes, o cluster experimental executará o código para manipular a falha como uma resposta malsucedida do cache. Fazemos isso assumindo que é tolerante a falhas, certo? Mas às vezes vemos que isso não é verdade. Do ponto de vista do serviço A, tudo parece um comportamento normal.
Controlamos cuidadosamente a engenharia do caos, o que pode dar muito errado. Quando a Netflix iniciou esses experimentos, não tínhamos um bom sistema de controle. Lançamos uma falha artificial e sentamos na sala, dedos cruzados e verificando se tudo estava funcionando bem. Agora temos muito mais atenção à segurança.
Analisamos as principais métricas de negócios. Um deles é chamado SPS (fluxo iniciado por segundo), ou seja, inicia fluxos de vídeo por segundo. Se você pensa no que é mais importante para os negócios da Netflix, é para que os usuários possam executar qualquer série a qualquer momento.

Nos gráficos, você vê um experimento real. Ele mostra a diferença no SPS entre os clusters experimental e de controle durante o teste. Você pode observar que os gráficos divergem bastante um do outro, o que não deveria ser, porque a mesma porcentagem de tráfego é enviada aos dois clusters.
Por esse motivo, o teste usa análise automatizada de canário. Emite um sinal de que muitos gráficos se desviaram muito um do outro. Nesse caso, o teste é imediatamente interrompido para que as pessoas possam trabalhar normalmente com o site. Do ponto de vista do usuário, isso é mais uma falha de curto prazo quando isso acontece.
Temos muitos outros remédios. Limitamos a quantidade de tráfego de teste em cada região, portanto, não realizamos o experimento apenas na zona Oeste dos EUA 2. Fazemos isso em qualquer lugar e limitamos o número de experimentos que podem ser realizados na região por vez. Os testes passam apenas durante o horário de trabalho, portanto, não acionaremos os engenheiros se algo der errado. Se o teste falhar, ele não poderá ser iniciado automaticamente novamente até que alguém o corrija explicitamente manualmente e confirme: "Ei, eu sei que o teste não passou, mas consertei tudo o que era necessário".
É possível aplicar propriedades customizadas aos clusters. Isso é útil se o serviço for dividido em shards, como muitos serviços da Netflix. Além disso, você pode implementar falhas com base no tipo de dispositivo. Se assumirmos algum problema nos dispositivos Apple ou em um determinado tipo de TV, podemos realizar testes especificamente para eles.
O ChAP encontrou muitos erros. Aqui está um dos meus favoritos. Realizamos um experimento para verificar o caminho de backup do serviço, que é crucial para sua disponibilidade, e identificamos um bug nesse local. O problema foi resolvido antes de levar ao incidente de disponibilidade do serviço. Este é um caso realmente interessante, porque esse caminho de backup não foi realizado com frequência. Portanto, o usuário realmente não sabia se estava funcionando corretamente e pudemos imitá-lo. Na verdade, causamos uma falha no serviço e verificamos se ele funcionava corretamente. Nesse caso, o usuário achou que seu serviço não era crítico ou secundário, mas, na verdade, era um serviço crítico.
Aqui está outro exemplo. Realizamos um experimento para reproduzir o problema durante o processo de registro, que apareceu à noite em alguns servidores. Algo estranho estava acontecendo com o serviço. O problema foi reproduzido após a introdução de um atraso de 500 milissegundos. Durante o teste, o problema foi encontrado nos logs enviados para o Big Data Portal. Isso ajudou a entender por que, em alguns casos, o registro não funcionou. Somente graças ao experimento ChAP conseguimos ver o que estava acontecendo e por quê.
A configuração do teste ChAP requer muita informação. Precisamos descobrir os pontos apropriados para a introdução de bugs. As equipes devem determinar se desejam travar ou atrasar. Tudo depende do ponto de injeção. Você pode travar o Cassandra, Hystrix (nosso sistema de backup), serviço RPC, cliente RPC, S3, SQS ou nosso cache ou adicionar um atraso a eles. Ou faça os dois. Você também pode criar combinações de diferentes experiências.
O que você precisa fazer é reunir-se com uma equipe de serviço e realizar um bom teste. Levará muito tempo. Ao configurar um experimento, você também deve definir configurações ACA (Automated Canary Analysis) ou configurações automáticas de canary.
Tivemos algumas configurações ACA prontas. Havia uma configuração de ChAP para o SPS. Havia um com indicadores do sistema de monitoramento. Outro que verificou o RPS falha. Outro certificou-se de que nosso serviço realmente funcione bem e implemente os erros corretamente. Percebemos que projetar um teste pode consumir muito tempo, e assim aconteceu. Não houve muitos testes criados. É difícil para uma pessoa ter em mente tudo o que é necessário para uma boa experiência. Decidimos automatizar algo com o ChAP. Analisamos os indicadores: para onde e para quem as chamadas são enviadas, arquivos com tempo limite, chamadas repetidas. Ficou claro que todas as informações vêm de lugares diferentes. Era necessário agregá-lo.
Escalamos a análise para o nível do ChAP, onde é muito mais conveniente trabalhar com informações e você pode usar o Monocle. Agora todas as informações sobre o aplicativo e o cluster podem ser estudadas em um único local. Aqui, cada linha representa uma dependência e essas dependências representam um terreno fértil para experimentos de engenharia do caos.
Coletamos todas as informações em um único local para o desenvolvimento do experimento, mas não entendemos que essa agregação é muito útil por si só, portanto esse é um efeito colateral interessante. Você pode ir aqui e ver anti-padrões associados a um serviço específico. Por exemplo, é detectada uma dependência que não foi considerada crítica, mas não possui uma rota de fallback. Obviamente, agora ela está se tornando crítica. As pessoas podem ver incompatibilidades de tempo limite, incompatibilidades de retorno de chamada. Usamos essas informações para avaliar a criticidade de um experimento de um determinado tipo e inseri-lo em um algoritmo que determina prioridades.
Cada linha representa uma dependência e essas linhas podem ser expandidas. Aqui está um exemplo interessante.

Aqui, a linha azul na parte superior indica o tempo limite de alguém e a linha roxa na parte inferior indica o tempo de execução usual. Como você pode ver, está muito, muito longe do tempo limite. Mas a maioria dessas informações não estava disponível. O que acontece se executarmos o teste logo após o tempo limite? O que você acha? Ele vai passar? Esta é uma pergunta interessante. Estamos tentando fornecer aos usuários esse nível de detalhe antes de executar os testes, para que eles possam tirar conclusões e alterar as configurações.
Eu quero jogar um joguinho. Há uma vulnerabilidade neste serviço Netflix, tente detectá-lo. Tome um segundo e olhe.


Para fornecer um contexto, o comando Hystrix remoto contém sample-rest-client e sample-rest-client.GET. O tempo limite do Hystrix é definido para 500 milissegundos. O Sample-Rest-Client.GET tem um tempo limite de 200 ms com uma nova tentativa, o que é bom, porque o total é de 400 milissegundos, que se encaixa no limite do Hystrix. O segundo cliente tem tempos limite de 100 e 600 com uma nova tentativa.
Nesse caso, a nova tentativa não pode ser concluída levando em consideração o tempo limite do shell Hystrix, ou seja, o Hystrix recusa a solicitação antes que o cliente possa receber uma resposta. É aqui que reside a vulnerabilidade. Nós fornecemos essas informações aos usuários. Curiosamente, a maior parte da lógica na implementação dessas funções está em lugares diferentes e antes que eles não pudessem comparar essas coisas. Eles pensaram que tudo estava funcionando bem, mas aqui está um bug.
Por que isso aconteceu? Obviamente, é fácil para um desenvolvedor ver o conflito e alterar o tempo limite, certo? Mas queremos descobrir o motivo. Podemos mudar o tempo limite, mas como podemos garantir que isso não ocorra novamente? Também ajudamos a descobrir os motivos.
Ao criar testes automatizados, também usamos o Monocle. O usuário cria uma experiência em vários tipos de dados de entrada. Tomamos tudo isso e automatizamos a criação de tais testes para que os usuários não se incomodem. Criamos e priorizamos automaticamente experimentos Hystrix e experimentos RPC com atrasos e falhas devido a atrasos. As configurações ACA são adicionadas por padrão. Temos SPC, métricas do sistema, estatísticas de consulta e experimentos executados automaticamente. Também são criadas prioridades para experimentos. Um algoritmo de alto nível funciona para eles. Usamos um balde com estatísticas de RPS. Usamos várias tentativas e comandos Hystrix relacionados. Todo o conjunto é ponderado adequadamente.
Além disso, são levados em consideração o número de equipes sem caminhos de execução de backup e qualquer impacto externo (impacto curado) que o cliente adiciona à sua dependência. Influências externas afetam bastante os procedimentos de autorização, registro e SPS. E realmente medimos seu efeito e não realizamos experimentos se o resultado for negativo. Em seguida, os testes são classificados e executados em ordem decrescente de criticidade. Quanto maior a pontuação de criticidade, mais cedo e com mais freqüência o teste é iniciado.
Ironicamente, o Monocle nos forneceu feedback que nos permite executar menos testes na produção. Realizamos tantos testes que, como resultado, um loop de feedback se formou: vimos as conexões entre os testes. Agora você pode olhar para arquivos de configuração específicos e ver antipadrões específicos. Mesmo sem testes para essas informações, é possível entender o que exatamente causará a falha, na época não tínhamos entendido isso antes.
Isso levou a um novo nível de segurança. Anteriormente, uma experiência malsucedida foi marcada como resolvida. Agora está marcado como resolvido antes do relançamento. Mas agora podemos adicionar explicitamente influências externas (curatoriais) ao vício. O usuário entra no monóculo e indica: esse fator influencia com precisão o procedimento de autorização. Este aqui está no SPC. E estamos trabalhando em um ciclo de feedback, para que, se ele falhar, um efeito curatorial também seja adicionado.
Assim, o Monocle no ChAP é uma ferramenta importante na qual todas as informações são coletadas, gera automaticamente experimentos, prioriza automaticamente e pesquisa por vulnerabilidades antes que elas levem a encerramentos em grande escala. Para resumir, é importante lembrar por que estamos envolvidos na engenharia do caos e realizar todas essas experiências na produção. Isso é feito para entender como os clientes usam o serviço e não perdê-los de vista. Você deseja fornecer às pessoas o serviço mais conveniente. Portanto, monitoramento e segurança são fundamentais. O Netflix sempre deve exibir vídeo.
Obrigada