Uma das coisas mais legais que aprendi no ano passado é como constantemente entregar valor à produção sem causar também muito caos.

Nesta postagem, explicarei a abordagem de desenvolvimento orientado por métricas e como isso me ajudou a alcançar isso. No final da postagem, você poderá responder às seguintes perguntas:

  • O que são métricas e por que devo usá-las
  • Quais são os diferentes tipos de métricas
  • Quais ferramentas eu poderia usar para armazenar e exibir métricas
  • O que é um exemplo do mundo real de desenvolvimento orientado por métricas

O que são métricas e por que devo usá-las?

As métricas permitem coletar informações em um sistema em execução ativa sem alterar seu código.

Ele permite que você obtenha dados valiosos sobre o comportamento do seu aplicativo enquanto ele é executado, para que você possa decisões orientadas a dados com base no feedback real do cliente e uso na produção.

Quais são os tipos de métricas disponíveis para mim?

Essas são as métricas mais comuns usadas hoje:

  • Contador – representa um valor crescente monotonicamente.

Screen Shot 5780 06 10 at 12.37.42 PM
Contadores são realmente úteis para medir taxas!

Neste exemplo, uma métrica de contador é usada para calcular a taxa de eventos ao longo do tempo, contando eventos por segundo

  • Medidor – Representa um único valor que pode aumentar ou diminuir.

Screen Shot 5780 06 10 at 12.42.06 PM
Os medidores são realmente úteis para medir o uso da CPU!

Neste exemplo, uma métrica de medidor é usada para monitorar o CPU do usuário em porcentagens

  • Histograma – Uma contagem de observações (como durações ou tamanhos de solicitações) em buckets configuráveis.

Screen Shot 5780 06 10 at 12.44.12 PM
Os histogramas são realmente úteis para medir a duração da solicitação!

Neste exemplo, uma métrica do histograma é usada para calcular os percentis 75 e 90 da duração de uma solicitação HTTP.

Os bits e bytes dos tipos: contador, histograma e bitola podem ser bastante confusos. Tente ler mais sobre isso aqui.

A maioria dos sistemas de monitoramento consiste em algumas partes:

  1. Banco de dados de séries temporais – Um software de banco de dados que otimiza o armazenamento e a veiculação séries temporais dados. Dois exemplos desse tipo de banco de dados são Sussurro e Prometeu.
  2. Mecanismo de consulta (com uma linguagem de consulta) – Dois exemplos de mecanismos de consulta comuns são: Grafite e PromQL
  3. Sistema de alerta – O mecanismo que permite configurar alertas com base em gráficos criados pelo idioma da consulta. O sistema pode enviar esses alertas para Mail, Slack, PagerDuty. Dois exemplos de sistemas de alerta comuns são: Grafana e Prometeu.
  4. Interface do usuário – Permite visualizar os gráficos gerados pelos dados recebidos e configurar consultas e alertas. Dois exemplos de sistemas de interface do usuário comuns são: Grafite e Grafana

A configuração que estamos usando hoje em BigPanda Engineering é

  • Telegraf– usado como um servidor StatsD.
  • Prometeu – usado como nosso mecanismo de sucateamento, banco de dados de séries temporais e mecanismo de consulta.
  • Grafana – usado para alertas e interface do usuário

E as restrições que tínhamos em mente ao escolher essa pilha eram:

  • Queremos raspagem de métricas escaláveis ​​e elásticas
  • Queremos um mecanismo de consulta com desempenho
  • Queremos consultar nossas métricas usando tags personalizadas (como nomes de serviço, hosts etc.)

Um exemplo real do desenvolvimento orientado por métricas de um serviço de análise de sentimentos

Vamos desenvolver um novo serviço de pipeline que calcula sentimentos com base em entradas de texto e o faz de maneira orientada a métricas de desenvolvimento!

Digamos que eu precise desenvolver este serviço de pipeline:

1 bj6DWm4987CuedEclpyvVw
Arquitetura de pipeline de análise de sentimentos

E este é o meu processo de desenvolvimento usual:

Screen Shot 5780 06 16 at 7.31.52 AM
Processo usual de desenvolvimento – Teste, codifique e implante. Oh meu!

Então, escrevo a seguinte implementação:

let senService: SentimentAnalysisService = new SentimentAnalysisService();while (true) {    let tweetInformation = kafkaConsumer.consume()    let deserializedTweet: { msg: string } = deSerialize(tweetInformation)    let sentimentResult = senService.calculateSentiment(deserializedTweet.msg)    let serializedSentimentResult = serialize(sentimentResult)    sentimentStore.store(sentimentResult);    kafkaProducer.produce(serializedSentimentResult, 'sentiment_topic', 0);}

A essência completa pode ser encontrada aqui .

E Tseu método funciona perfeitamente bem.

Mas o que acontece quando não acontece?

but

A realidade é que, enquanto trabalhamos (em um processo de desenvolvimento ágil), cometemos erros. Isso é um fato da vida.

Acredito que o verdadeiro desafio de cometer erros não é evitá-los, mas otimizar a rapidez com que os detectamos e reparamos. Então, precisamos ganhar a capacidade de rapidamente descubra nossos erros.

Está na hora do MDD-way.

A maneira MDD (Metrics Driven Development)

commandments
Ver! Os três mandamentos da produção!

A abordagem MDD é fortemente inspirada no Três mandamentos de produção (que eu aprendi da maneira mais difícil).

o Três Os mandamentos da produção são:

  1. Existem erros e bugs no código que você escreve e implanta.
  2. Os dados que fluem na produção são imprevisíveis e único!
  3. Aperfeiçoe seu código de feedback real do cliente e uso na produção.

E já que agora sabemos o Mandamentos, é hora de revisar o plano de quatro etapas do processo de desenvolvimento orientado a métricas.

O plano de quatro etapas para um MDD bem-sucedido

MDD oh wow
Desenvolvimento orientado por métricas 😍

Desenvolver código

Escrevo o código e, sempre que possível, envolvo-o com um sinalizador de recurso que me permite abri-lo gradualmente para os usuários.

Métricas

Isso consiste em duas partes:

Adicione métricas às partes relevantes

Nesta parte, pergunto-me quais são as métricas de sucesso ou falha que posso definir para garantir que meu recurso funcione? Nesse caso, meu novo aplicativo de pipeline executa sua lógica corretamente?

Adicione alertas sobre eles para que eu seja alertado quando ocorrer um erro

Nesta parte, pergunto-me: Qual métrica poderia me alertar se eu esquecesse algo ou não o implementasse corretamente?

Desdobramento, desenvolvimento

Implantei o código e o monitoro imediatamente para verificar se ele está se comportando como eu previa.

Iterar esse processo com perfeição

E é isso! Agora que aprendemos o processo, vamos abordar uma tarefa importante dentro dele.

Métricas a serem reportadas – o que devemos monitorar?

Uma das perguntas mais difíceis para mim, quando estou fazendo MDD, é: “o que devo monitorar”?

MALLTHINGZ
É um gif adorável. mas pouco realista na maioria dos casos.

Para responder à pergunta, vamos tentar diminuir o zoom e olhar para o quadro geral.
Todas as informações possíveis disponíveis para monitorar podem ser divididas em duas partes:

  1. Informações aplicáveis– Informações que possuem um contexto e significado aplicativos. Um exemplo disso será: “Quantos tweets classificamos como positivos na última hora”?
  2. Informação operacional– Informações relacionadas à infraestrutura que envolve nosso aplicativo – Dados na nuvem, utilização da CPU e do disco, uso da rede etc.

Agora, como não podemos monitorar tudo, precisamos escolher quais informações operacionais e aplicativos queremos monitorar.

  • A parte operacional realmente depende da pilha de operações e possui soluções integradas para (quase) todas as suas necessidades de monitoramento.
  • A parte do aplicativo é mais exclusiva para as suas necessidades e tentarei explicar como penso sobre isso mais adiante neste post.

Depois disso, podemos nos perguntar: que alertas queremos configurar sobre as métricas que acabamos de definir?

O diagrama (de informações, métricas, alertas) pode ser desenhado assim:

world of
O mundo das informações, métricas e alertas.

Métricas aplicáveis

Normalmente, adiciono métricas de aplicativos a partir de duas necessidades:

Para responder perguntas

Uma pergunta é algo como “Quando meu serviço se comporta mal, quais informações seriam úteis para você saber?”

Algumas respostas para essa pergunta podem ser: latências de todas as chamadas de entrada / saída, taxa de processamento, taxa de transferência, etc.

A maioria dessas perguntas será útil enquanto você estiver procurando a resposta. Mas uma vez que você o encontrou, é provável que não o veja novamente (já que você já sabe a resposta).

Essas perguntas são geralmente conduzidas pelo RND e são (geralmente) usadas para coletar informações internamente.

Para adicionar alertas

Isso pode parecer um atraso, mas geralmente adiciono métricas de aplicativos para definir alertas sobre elas. Ou seja, definimos a lista de alertas e, em seguida, deduzimos deles quais são as métricas aplicáveis ​​a serem relatadas.

Esses alertas são derivados do SLA do produto e geralmente são tratados com importância de missão crítica.

Tipos comuns de alertas

Os alertas podem ser divididos em três partes:

alert types
Alertas tipos à lista Métricas

Alertas de SLA

sla breach
Alertas de SLA na realidade

SLA alertas cercam os locais em nosso sistema onde um SLA é especificado para atender a requisitos explícitos do cliente ou internos (ou seja, disponibilidade, taxa de transferência, latência etc.) As violações de SLA envolvem a paginação de RND e a ativação de pessoas. Portanto, tente manter os alertas nesta lista no mínimo.

Além disso, podemos definir Degradação Alertas, além dos Alertas do SLA.
Os alertas de degradação são definidos com limites mais baixos que os alertas do SLA e, portanto, são úteis na redução da quantidade de violações do SLA – fornecendo um aviso adequado antes que eles aconteçam.

Um exemplo de alerta de SLA seria: “Todas as solicitações de sentimentos devem terminar em menos de 500 ms.”

Um exemplo de alerta de degradação será: “Todas as solicitações de sentimentos devem terminar em menos de 400 ms”.

Estes são os alertas que defini:

  1. Latência – espero que o percentil 90 de uma única duração de solicitação não exceda 300ms.
  2. Taxa de solicitações de êxito / falha – Espero que o número de falhas por segundo, sucesso por segundo, permaneça abaixo de 0,01.
  3. Taxa de transferência – espero que o número de operações por segundo (ops) que o aplicativo manipula seja> 200
  4. Tamanho dos dados – Espero que a quantidade de dados que armazenamos em um único dia não exceda 2 GB.

200 ops * 60 bytes (tamanho do resultado da opinião) * 86400 s em um dia = 1 GB <2 GB

Alertas de violação da linha de base

Esses alertas geralmente envolvem medir e definir uma linha de base e garantir que ela não mude (drasticamente) ao longo do tempo com os alertas.

Por exemplo, a 99ª latência de processamento de um evento deve permanecer relativamente a mesma ao longo do tempo, a menos que tenhamos feito mudanças drásticas na lógica.

Estes são os alertas que defini:

  1. Quantidade de tweets de sentimento positivo, neutro ou negativo – se por qualquer motivo, a soma de tweets positivos aumentar ou diminuir drasticamente, talvez eu tenha um bug em algum lugar do meu aplicativo.
  2. Toda a latência Taxa de sucesso de solicitações Taxa de transferência Tamanho dos dados não deve aumentar diminuir drasticamente ao longo do tempo.

Alertas de propriedades de tempo de execução

Eu falei sobre Testes baseados em propriedades e sua força insana. Como se vê, a coleta de métricas nos permite executar testes baseados em propriedades em nosso sistema em produção!

Algumas propriedades do nosso sistema:

  1. Como consumimos mensagens de um tópico Kafka, o deslocamento manipulado deve aumentar monotonicamente ao longo do tempo.
  2. 1 ≥ pontuação de sentimento ≥ 0
  3. Um tweet deve ser classificado como Negativo Positivo Neutro.
  4. Uma classificação de tweet deve ser única.

Esses alertas me ajudaram a validar que:

  1. Estamos lendo com o mesmo ID de grupo. Alterar os IDs de grupos de consumidores por engano na implantação é um erro comum ao usar o Kafka. Causa muito caos na produção.
  2. A pontuação do sentimento é consistentemente entre 0 e 1.
  3. O tamanho da categoria do Tweet deve sempre ser 1.

Para definir esses alertas, você precisa enviar métricas do seu aplicativo. Ir aqui para a lista completa de métricas.

Usando essas métricas, eu posso criar alertas isso me paginará sempre que uma dessas propriedades não permanecer mais em produção.

processing latency alert
A latência de processamento violou o SLA configurado! Oh meu! 😱

Vamos dar uma olhada em uma possível implementação de todas essas métricas

import SDC = require("statsd-client");let sdc = new SDC({ host: 'localhost' });let senService: SentimentAnalysisService; //...while (true) {    let tweetInformation = kafkaConsumer.consume()    sdc.increment('incoming_requests_count')    let deserializedTweet: { msg: string } = deSerialize(tweetInformation)    sdc.histogram('request_size_chars', deserializedTweet.msg.length);    let sentimentResult = senService.calculateSentiment(deserializedTweet.msg)    if (sentimentResult !== undefined) {        let serializedSentimentResult = serialize(sentimentResult)        sdc.histogram('outgoing_event_size_chars', serializedSentimentResult.length);        sentimentStore.store(sentimentResult)        kafkaProducer.produce(serializedSentimentResult, 'sentiment_topic', 0);    }}

O código completo pode ser encontrado aqui

Algumas reflexões sobre o exemplo de código acima:

  1. Houve uma quantidade impressionante de métricas adicionadas a essa base de código.
  2. As métricas adicionam complexidade à base de código; portanto, como todas as coisas boas, adicione-as com responsabilidade e com moderação.
  3. É difícil escolher nomes de métricas corretos. Não se apresse em selecionar nomes próprios. Aqui estáum excelente post sobre isso.
  4. Você ainda precisa coletar essas métricas e exibi-las em um sistema de monitoramento (como o Grafana), além de adicionar alertas sobre elas, mas esse é um tópico para uma postagem diferente.

Atingimos o objetivo inicial de identificar problemas e resolvê-los mais rapidamente?

yes it was
YESSSS, foi!

Agora podemos garantir que a latência e a taxa de transferência do aplicativo não diminuam com o tempo. Além disso, a adição de alertas nessas métricas permite uma descoberta e resolução de problemas muito mais rápidas.

Conclusão

O desenvolvimento orientado por métricas acompanha o CI CD, DevOps e o processo de desenvolvimento ágil. Se você estiver usando alguma das palavras-chave acima, estará no lugar certo.

Quando bem feitas, as métricas fazem você se sentir mais confiante em sua implantação, da mesma maneira que ver passar nos testes de unidade em sua compilação faz com que você se sinta confiante no código que escreve.

A adição de métricas permite implantar código e ter certeza de que seu ambiente de produção é estável e que seu aplicativo está se comportando conforme o esperado ao longo do tempo. Por isso, encorajo-o a experimentar!

Algumas referências

  1. Aqui está um ligação para o código mostrado nesta postagem e aqui é a lista completa de métricas descrita.
  2. Se você está ansioso para tentar escrever algumas métricas e conectá-las a um sistema de monitoramento, confira Prometeu, Grafanae possivelmente isso postar
  3. Esse cara escreveu uma deliciosa postarsobre desenvolvimento orientado por métricas. Vá ler.



Fonte