Rastreio Distribuído
O Rastreio Distribuído é um mecanismo para coletar solicitações individuais através dos limites de microsserviços. Ele também permite a instrumentação da latência do aplicativo (quanto tempo cada solicitação levou), acompanhando o ciclo de vida das chamadas de rede (HTTP, RPC, etc.) e também identifica problemas de desempenho, obtendo visibilidade dos gargalos. Muitos artigos estão nas inter-webs descrevendo várias implementações do Distributed Tracing. Este blog se concentrará em nossa experiência em rastrear nosso ecossistema com histórias sobre o que não fazer.
O que precisamos resolver
Avance Network possui centenas de microsserviços rodando sobre o Kubernetes. Temos métricas por meio do painel Prometheus e Hystrix para monitorar a integridade geral, mas não temos visibilidade nas solicitações de negócios. Por exemplo, quando um usuário clica em um anúncio, queremos ver o fluxo exato. Em particular, convém ver a solicitação / resposta do lance para nossos parceiros por motivos de desempenho ou fraude. Mas não temos algo que nos permita examinar uma solicitação individual. É isso que o rastreamento resolve para nós; a capacidade de capturar a lógica de negócios exata para uma solicitação específica. O rastreamento pode responder a essas perguntas:
Eu bati no cache ou fui a um armazenamento de dados? Quais serviços foram usados para essa solicitação específica de lógica de negócios?
Implementamos o rastreamento para visualizar e armazenar nossos rastreamentos:
A primeira regra
A primeira regra do rastreamento é que ninguém deve saber sobre o rastreamento. O rastreamento deve estar atrás de uma cortina mágica de abstração; tudo sem o conhecimento dos desenvolvedores. Dependendo das práticas de desenvolvimento da sua organização e do uso da infraestrutura principal (por exemplo, clientes HTTP, estrutura RPC, drivers de banco de dados ... etc), isso pode ser difícil. Mas se a maioria da sua organização usa um ou dois clientes HTTP (ou seja, OkHttp, Apache HTTP), é um instrumento trivial para aqueles clientes com recursos de rastreamento sem muita intervenção do desenvolvedor. Ao instrumentar apenas clientes e servidores HTTP, você obterá um grande benefício com o rastreamento. Pense na regra 80/20 ao planejar sua implementação de rastreamento.
O que não fazer
Conceitual, o rastreamento é fácil de entender. Operacionalmente, pode se transformar em uma bagunça. Há uma sobrecarga no rastreamento, embora pequeno, mas você ainda não deseja obter erros OutOfMemory por causa do rastreamento. Portanto , não comece a rastrear tudo !
Além disso, se você começar a rastrear tudo o que fará com todos esses dados? Dependendo do carregamento da sua solicitação, isso pode ser enorme. Claro, você resolveu rastrear seus microsserviços, mas criou uma quantidade enorme de dados (e hardware) que provavelmente ninguém vai ver. No começo, mantenha seus custos operacionais em um nível mínimo. Você pode começar despejando rastreamentos em sua infraestrutura de log existente (por exemplo, coloque o ID de rastreamento como contexto MDC em todas as instruções de log). Não é necessário hardware extra (colecionador)! Como projetar software, comece pequeno e aumente suas alterações com o tempo.
Lento e constante vence a corrida
Comece sua busca de rastreamento fornecendo um mecanismo que “ative” o rastreamento manualmente. Suponha que você tenha uma API REST, detectando um cabeçalho de solicitação especial, diga “ X-AdHocTrace ”, informará o serviço que o rastreamento foi solicitado. Isso permitirá o rastreamento para todos os servidores downstream também. Usamos o swagger e adicionamos o cabeçalho automaticamente:
window.onload = function () { const ui = SwaggerUIBundle({ url: "../api/swagger/apiDocs", requestInterceptor: function (request) { request.headers ['X-AdHocTrace'] = "true"; solicitação de retorno;}
Quando os desenvolvedores estão testando seus serviços (local ou remotamente), eles automaticamente recebem todas as suas chamadas rastreadas ao usar o swagger.
Horas extras, você pode adicionar mecanismos de amostragem mais sofisticados . Por exemplo, você pode provar todas as solicitações que resultam em um código de status HTTP 500.
É uma armadilha
Apesar de estar por um tempo, o mundo do rastreamento não tem padrões oficiais. Certamente, existem ZipKin, OpenTracing e OpenCensus, mas
são estruturas e implementações opinativas de rastreamento. Há um grupo de trabalho do W3C em andamento e, em seguida, há soluções proprietárias de fornecedores. Não use estruturas de rastreamento prontas para uso e exponha-as como uma dependência direta no seu código. Em vez disso, crie um rastreador empacotado que imite um rastreador conhecido e o adapte à sua própria organização. Trate o rastreador como uma combinação de métricas e registrador. Oculte a criação de rastreamentos internamente para componentes, por exemplo, driver JDBC, mas permite que os desenvolvedores aprimorem ou aprimorem o rastreamento com lógica específica de negócios:
classe pública UserDao { rastreador estático rastreador = TracerProvider.getTracer (); exclusão booleana pública (ID do usuário longo) { tracer.log ("excluindo usuário" + ID do usuário); tracer.tag ("userId", userId) // Ou use uma tag ... }}
O rastreio seja ágil. Rastrear seja silencioso.
Adotamos uma abordagem rápida e silenciosa na infraestrutura de rastreamento. Usamos métricas para registrar atividades de rastreamento, como taxas de criação de abrangência e erros internos de rastreabilidade. Decidimos não registrar erros de rastreamento, pois isso pode bombardear um aplicativo com logs que os proprietários não saberão resolver. Teste o que aconteceria se o coletor de rastreio não responder ou demorar para aceitar solicitações. O aplicativo deve se comportar normalmente, mesmo quando a infraestrutura de rastreamento desmorona.
Outro truque que usamos foi empacotar tags e (trace) logs com lambdas (Fornecedor no léxico JAVA). Se você tiver uma tag cara, digamos um corpo de solicitação, use uma lambda:
tracer.withTag ("body", () - objectMapper.writeValueAsString (pojo))
Devido à abordagem de rastreamento ad hoc, são executadas apenas uma pequena fração do tempo, economizando desempenho.
Testes de integração
Você tem teste de integração ou um ambiente simulado? Por que não ativar o rastreamento nos testes? É uma boa maneira de ver como o rastreamento se comporta em quase produção, como cenários, sem sobrecarregar seus serviços. O outro benefício é que, quando um teste falha, você tem um rastreamento que pode ajudá-lo a solucionar problemas.
Em conclusão
Trate o rastreamento como ferramenta de monitor adicional no ecossistema, não como um substituto. Comece devagar, aumente suas alterações, seja silencioso e tenha desempenho neutro. Nós abstraímos a criação de extensões dentro de nossa própria estrutura para que os desenvolvedores não criem elas mesmas. Por fim, trate o rastreador como uma combinação de log e métricas.
Para mim, o insight mais valioso do rastreamento foi o entendimento detalhado dos fluxos de negócios. Um novo funcionário que ingressa em uma equipe pode examinar um rastreamento para ver o caminho crítico do código para solicitações de negócios específicas. A revisão de rastreios possui um recurso de autodocumentação que não esperávamos.