Engenharia

Rastreamento distribuído, OpenTracing e Elastic APM

O mundo dos microsserviços

As empresas estão cada vez mais adotando arquiteturas de microsserviços. Elas estão desenvolvendo e implantando mais microsserviços a cada dia que passa. Com frequência, esses serviços são desenvolvidos em diferentes linguagens de programação, implantados em containers de tempo de execução separados e gerenciados por diferentes equipes e organizações. Grandes empresas como Twitter podem ter dezenas de milhares de microsserviços, sendo que todos eles trabalham juntos para atingir as metas de negócios. Conforme discutido nesta postagem de blog do Twitter, a visibilidade na integridade e no desempenho da topologia de serviços diversos é extremamente importante para poder determinar rapidamente a principal causa dos problemas, além de aumentar a confiabilidade e eficiência geral do Twitter.

É nessa hora que oRastreamento distribuído realmente pode ajudar. O rastreamento distribuído ajuda em dois desafios fundamentais enfrentados pelos microsserviços:

  1. Rastreamento de latência
    Uma solicitação ou transação de usuário pode percorrer muitos serviços diferentes em ambientes de tempo de execução diferentes. Entender a latência de cada um desses serviços para uma determinada solicitação é crucial para entender as características de desempenho geral do sistema como um todo, além de proporcionar uma visão valiosa para possíveis melhorias.
  2. Análise das causas principais
    A análise das causas principais representa um desafio ainda maior para aplicativos criados com base em grandes ecossistemas de microsserviços. Qualquer coisa pode dar errada com qualquer serviço a todo momento. O rastreamento distribuído tem importância crucial ao resolver problemas nesse tipo de sistema.

Recapitulando, o rastreamento é apenas uma das peças do quebra-cabeças dos Três pilares da observabilidade — log, métrica e rastreamento. Conforme trataremos brevemente, o Elastic Stack é uma plataforma unificada para os três pilares da observabilidade. Quando os logs, as métricas e os dados de APM são armazenados no mesmo repositório, analisados e correlacionados juntos, você obtém a visão mais bem contextualizada dos aplicativos e sistemas de negócios. Neste blog, nosso foco será exclusivamente no aspecto do rastreamento.

Rastreamento distribuído com o Elastic APM

O Elastic APM é um sistema de monitoramento de desempenho de aplicativos criado com base no Elastic Stack. Ele permite monitorar serviços de software e aplicativos em tempo real, coletando informações de desempenho detalhadas sobre tempo de resposta para solicitações recebidas, consultas de banco de dados, chamadas a caches, solicitações HTTP externas etc. Os agentes do Elastic APM oferecem sofisticada instrumentação automática imediatamente (p. ex.: timing db queries, etc.) para estruturas e tecnologias compatíveis. Você também pode usar instrumentação personalizada para finalidades personalizadas. Isso facilita muito a rápida identificação e correção de problemas de desempenho.

O Elastic APM oferece suporte a rastreamento distribuído e é compatível com o OpenTracing. Ele permite analisar o desempenho em toda a arquitetura de microsserviços em uma única visualização. Para fazer isso, o Elastic APM rastreia todas as solicitações, como a solicitação Web inicial, o serviço de front-end e as consultas feitas aos serviços de back-end. Assim, fica muito mais fácil e rápido descobrir possíveis gargalos no aplicativo. A visualização Timeline (Linha do tempo) na IU do APM mostra uma visualização em cascata de todas as transações partindo dos serviços individuais que estão conectados em um rastreamento:

O Elastic Stack também é uma ótima plataforma para agregação de logs e análise de métricas. Ter logs, métricas e rastreamentos de APM armazenados e indexados no Elasticsearch é bastante eficaz. Ser capaz de correlacionar rapidamente fontes de dados como métricas de infraestrutura, logs e rastreamentos permite depurar a causa principal bem mais rapidamente. Na UI de APM, ao analisar um rastreamento, você pode saltar rapidamente para as métricas e os logs de host ou container clicando no menu Actions (Ações), se essas métricas e logs também forem coletados.

Seria maravilhoso se todos estivessem usando o Elastic APM para instrumentar seus aplicativos e serviços. Entretanto, o Elastic APM não é a única solução de rastreamento distribuído disponível hoje. Existem outros rastreadores open source conhecidos como Zipkin e Jaeger. Conceitos como programação de polígonos e persistência poliglota são bem conhecidos e aceitos no mundo dos microsserviços. Da mesma maneira, o “rastreamento poliglota” segue a tendência de ficar mais comum. Devido à natureza independente e desconectada dos microsserviços, pessoas responsáveis por diferentes serviços provavelmente usarão diferentes sistemas de rastreamento.

Desafios para desenvolvedores

Com muitos sistemas de rastreamento diferentes disponíveis, os desenvolvedores enfrentam desafios reais. Ao final do dia, os rastreadores vivem dentro do código do aplicativo. Alguns desafios comuns são:

  1. Qual sistema de rastreamento usar?
  2. E se eu quiser alterar meu rastreador? Não quero alterar todo o meu código-fonte.
  3. O que faço com bibliotecas compartilhadas que podem estar usando diferentes rastreadores?
  4. E se meus serviços de terceiros usarem diferentes rastreadores?

Não é nenhuma surpresa que precisamos de padronização para atender a essas preocupações. Antes de tratar da posição em que estamos na padronização, vamos recapitular e analisar um rastreamento distribuído de uma perspectiva arquitetônica e de maneira holística e entender o que é necessário para atingir o auge do rastreamento distribuído.

Componentes arquitetônicos do rastreamento distribuído

Os sistemas de software modernos podem ser desmembrados em alguns componentes de alto nível, normalmente projetados e desenvolvidos por diferentes organizações e executados em diferentes ambientes de tempo de execução.

  • Seus próprios códigos de aplicativo e serviços
  • Bibliotecas e serviços compartilhados
  • Serviços externos

Para monitorar esse sistema de maneira holística e integrada com rastreamento distribuído, precisamos de quatro componentes arquitetônicos:

  1. API de rastreamento distribuído padronizada. Uma API de rastreamento independente de fornecedor padronizada permite aos desenvolvedores instrumentar seu código de maneira padronizada, independentemente de qual rastreador eles possam escolher usar posteriormente durante o tempo de execução. Essa é a primeira etapa antes de mais nada.
  2. Definição e propagação do contexto de rastreamento padronizado. Para que um rastreamento vá de um tempo de execução a outro, o contexto de rastreamento precisa ser entendido por ambas as partes e é necessário haver um método padrão de propagar esse contexto. No mínimo, o contexto carrega um ID de rastreamento.
  3. Definição de dados de rastreamento padronizada. Para que os dados de rastreamento de um rastreador sejam entendidos e consumidos por outro rastreador, é necessário ter um formato padronizado e extensível para eles.
  4. Rastreadores interoperáveis. Por fim, para atingir absoluta compatibilidade de tempo de execução, diferentes rastreadores precisam fornecer mecanismos para eles para exportar e importar dados de rastreamento de outros rastreadores de maneira aberta. O ideal é que uma biblioteca compartilhada ou serviço instrumentado por um rastreador como o Jaeger fosse capaz de ter seus dados de rastreamento enviados diretamente ao Elastic APM ou outro rastreador através do agente Jaeger por meio de uma alteração de configuração.

Agora, acesse o OpenTracing.

A especificação do OpenTracing

A especificação do OpenTracing define uma API independente de fornecedor e aberta para rastreamento distribuído. Ela permite aos usuários evitar a dependência de fornecedores permitindo-lhes trocar o implementador do OpenTracing a qualquer momento. Também permite aos desenvolvedores de estruturas e bibliotecas compartilhadas fornecer a funcionalidade de rastreamento imediatamente e de maneira padrão para proporcionar visões melhores das estruturas e bibliotecas. Empresas em escala Web como Uber e Yelp estão usando o OpenTracing para obter uma visibilidade mais profunda de seus aplicativos altamente distribuídos e dinâmicos.

O modelo de dados do OpenTracing

Os conceitos básicos do OpenTracing e do modelo de dados fundamental vieram do documento Dapper do Google. Os conceitos cruciais incluem rastreamento e período.

  1. Um rastreamento representa uma transação à medida que percorre um sistema distribuído. Ele pode ser considerado um gráfico acíclico dirigido de períodos.
  2. Um período representa uma unidade lógica de trabalho que tem um nome, uma hora de início e uma duração. Os períodos podem ser aninhados e ordenados para modelar relacionamentos. Os períodos aceitam marcas key:value, além de logs estruturados de granularidade fina e com carimbo de tempo anexados a determinada instância de período.
  3. O contexto do rastreamento consiste nas informações de rastreamento que acompanham a transação distribuída, incluindo quando ela passa do serviço para o serviço pela rede ou por um barramento de mensagens. O contexto contém o identificador do rastreamento, o identificador do período e quaisquer outros dados de que o sistema de rastreamento precisa para se propagar para o serviço downstream.

E como é que tudo se ajusta?

O ideal é que, com a padronização, as informações de rastreamento do código do aplicativo personalizado, das bibliotecas compartilhadas e dos serviços compartilhados desenvolvidos e executados por diferentes organizações sejam intercambiáveis e compatíveis com o tempo de execução, independentemente de qual rastreador cada um desses componentes escolheu usar.

Entretanto, o OpenTracing aborda somente o primeiro dos quatro componentes arquitetônicos que tratamos antes. Assim, em que posição estamos hoje com os outros componentes e o que o futuro nos reserva?

Em que posição estamos hoje?

Conforme discutimos, o OpenTracing define um conjunto padrão de APIs de rastreamento para diferentes rastreadores implementarem, o que é um bom começo e um grande incentivo. Entretanto, ainda precisamos da padronização do contexto e dos dados de rastreamento para que fiquem compatíveis e intercambiáveis entre si.

  1. A API do OpenTracing fornece um conjunto padrão de APIs. Essa é a única padronização disponível até hoje. Também há limitação à especificação. Por exemplo, ela não cobre todas as linguagens de programação. Entretanto, trata-se de um esforço admirável e que está ganhando enorme potencial.
  2. Não há ainda nenhuma definição de contexto de rastreamento padronizada. O W3C Distributed Tracing Work Group está no processo de padronizar a definição do contexto de rastreamento — a especificação de contexto de rastreamento do W3C. A especificação define uma abordagem unificada à correlação de contexto e evento em sistemas distribuídos e permitirá rastreamento de transações end-to-end em aplicativos distribuídos entre diferentes ferramentas de monitoramento. O Elastic APM oferece suporte ao esforço do grupo de trabalho de contexto de rastreamento do W3C para padronizar o formato de cabeçalho HTTP para rastreamento distribuído. Nossas implementações de agente seguem estritamente a especificação de rascunho de contexto de rastreamento, e pretendemos oferecer suporte total à especificação final.

    Como exemplo da incompatibilidade do contexto de rastreamento hoje, a seguir está um exemplo do cabeçalho HTTP usado pelo Elastic APM e Jaeger para ID de rastreamento. Como você pode ver, tanto o nome quanto a codificação do ID são diferentes. Quando diferentes cabeçalhos de rastreamento forem usados, os rastreamentos serão rompidos quando cruzarem as fronteiras das respectivas ferramentas de rastreamento.

    Jaeger:
    uber-trace-id: 118c6c15301b9b3b3:56e66177e6e55a91:18c6c15301b9b3b3:1

    Elastic APM:
    elastic-apm-traceparent: 00-f109f092a7d869fb4615784bacefcfd7-5bf936f4fcde3af0-01

    Também há outros desafios, além da definição em si. Por exemplo, nem todos os cabeçalhos HTTP são encaminhados automaticamente pela infraestrutura de serviço e pelos roteadores etc. Sempre que os cabeçalhos forem ignorados, o rastreamento será rompido.
  3. Não há ainda nenhuma definição de dados de rastreamento padronizada. Conforme mencionado pelo W3C Distributed Tracing Work Group, a segunda peça do quebra-cabeças para interoperabilidade de rastreamento é “um formato padronizado e extensível para compartilhar dados de rastreamento — rastreamentos completos ou fragmentos — entre as ferramentas para interpretação adicional”. Como você pode imaginar, com muitos participantes open source e comerciais envolvidos, concordar com um formato padrão não é uma tarefa fácil. Nossa expectativa é conseguirmos isso em breve.
  4. Os rastreadores não são compatíveis com tempo de execução. Devido a todos os aspectos abordados anteriormente, além da motivação mista de tornar seu sistema open source e compatível com o restante do mundo, os rastreadores simplesmente não são compatíveis entre si durante o tempo de execução na atualidade. Posso seguramente afirmar que esse será o caminho no futuro.

Como o Elastic APM funciona com outros rastreadores hoje em dia

Mesmo que não estejamos nem próximos da compatibilidade absoluta entre os rastreadores ainda hoje, não é preciso perder as esperanças. O Elastic Stack ainda pode funcionar com outros rastreadores de várias maneiras diferentes.

  1. O Elasticsearch como armazenamento de dados de back-end escalável para outros rastreadores.

    Não é nenhuma surpresa que o Elasticsearch é usado como armazenamento de dados de back-end para outros rastreadores como Zipkin e Jaeger, devido à sua escalabilidade maciça e aos sofisticados recursos de análise. Colocar dados de rastreamento do Zipkin ou Jaeger no Elasticsearch é uma configuração simples para ambos. Depois que os dados de rastreamento estiverem no Elasticsearch, você poderá usar o poderoso recurso de análise e visualização do Kibana para analisar as informações de rastreamento e criar visualizações atraentes que oferecem uma visão profunda do desempenho do aplicativo.
  2. Ponte Elastic OpenTracing

    A ponte Elastic APM OpenTracing permite criar transações e períodos do Elastic APM, usando a API do OpenTracing. Em outras palavras, ela transforma as chamadas feitas à API do OpenTracing em Elastic APM, possibilitando o reúso da instrumentação existente. Por exemplo, uma instrumentação existente feita pelo Jaeger pode ser substituída simplesmente pelo Elastic APM alterando algumas linhas de código.

    Instrumentação original feita pelo Jaeger:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import io.jaegertracing.Configuration;
    import io.jaegertracing.internal.JaegerTracer;
    ...
    private void sayHello(String helloTo) {
        Configuration config = ...
        Tracer tracer = config.getTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        
    Substitua o Jaeger pela ponte Elastic OpenTracing:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import co.elastic.apm.opentracing.ElasticApmTracer;
    ...
    private void sayHello(String helloTo) {
        Tracer tracer = new ElasticApmTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        


    Com essa alteração simples, os dados de rastreamento fluirão satisfatoriamente para o Elastic APM, sem a necessidade de modificar outra parte do código de rastreamento. Essa é a capacidade do OpenTracing!

Monitoramento de usuários reais do Elastic APM

Apesar de nosso foco principal estar nos serviços de back-end ao discutir, por exemplo, propagação de rastreamento e contexto, há um grande valor para iniciar o rastreamento no lado do cliente do navegador. Ao fazer isso, você obtém informações de rastreamento no momento que um usuário clica em alguma parte no navegador. As informações de rastreamento representam a “experiência do usuário real” dos aplicativos sob o aspecto do desempenho. Mais uma vez é lamentável dizer que não há uma maneira padronizada de encaminhar essas informações na atualidade. O grupo W3C não pretende estender o contexto de rastreamento completamente para o navegador no futuro.

O Elastic APM Real User Monitoring (RUM) fornece exatamente essa funcionalidade atualmente. O agente RUM JS monitora a experiência do usuário real no aplicativo do lado do cliente. Você poderá mensurar métricas como "Time to First Byte", domInteractive e domComplete, o que ajuda a descobrir problemas de desempenho no aplicativo do lado do cliente, além de problemas relativos à latência do aplicativo do lado do servidor. Nosso agente RUM JS oferece neutralidade de estrutura, o que significa que ele pode ser usado com qualquer aplicativo de front-end baseado em JavaScript.

<p?</p?

Resumo

Espero que este blog tenha ajudado você a entender um pouco melhor o panorama do rastreamento distribuído e esclarecido algumas das confusões sobre nossa posição atual em relação ao OpenTracing. Vamos concluir com um breve resumo:

  1. O rastreamento distribuído oferece uma visão de desempenho inestimável para os microsserviços.
  2. O OpenTracing é a primeira etapa do setor rumo à padronização para o rastreamento distribuído. Ainda temos um longo caminho a percorrer para permitir a total compatibilidade.
  3. O Elastic APM é compatível com o OpenTracing.
  4. A ponte Elastic OpenTracing permite o reúso da instrumentação.
  5. O Elastic Stack é um excelente armazenamento escalável no longo prazo para outros rastreadores como o Zipkin e o Jaeger, mesmo não oferecendo total compatibilidade de tempo de execução atualmente.
  6. A Elastic fornece análise sofisticada para dados de rastreamento da Elastic. O envio de dados de rastreamento do Zipkin ou Jaeger para o Elasticsearch é uma configuração simples.
  7. O Elastic APM Real User Monitoring (RUM) monitora a experiência do usuário real no aplicativo do lado do cliente.
  8. No geral, a Elastic é uma plataforma de análise unificada, maciçamente escalável e sofisticada em recursos para os três pilares da observabilidade — log, métrica e rastreamento.

Como sempre, acesse o fórum do Elastic APM se quiser abrir uma discussão ou tiver dúvidas. Bom rastreamento!