BLOG | NGINX

OpenTracing para NGINX e NGINX Plus

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Mohamed Gougam Miniatura
Mohamed Gougam
Publicado em 17 de junho de 2019

Apesar de todos os seus benefícios, uma arquitetura de microsserviços também introduz novas complexidades. Um deles é o desafio de rastrear solicitações à medida que são processadas, com dados fluindo entre todos os microsserviços que compõem o aplicativo. Uma nova metodologia chamada rastreamento distribuído (solicitação) foi inventada para esse propósito, e o OpenTracing é uma especificação e conjunto padrão de APIs destinadas a orientar o design e a implementação de ferramentas de rastreamento distribuído.

No NGINX Plus Release 18 (R18) , adicionamos o módulo NGINX OpenTracing ao nosso repositório de módulos dinâmicos (ele está disponível como um módulo de terceiros no GitHub há alguns anos). Uma grande vantagem do módulo NGINX OpenTracing é que, ao instrumentar o NGINX e o NGINX Plus para rastreamento distribuído, você obtém dados de rastreamento para cada aplicativo com proxy, sem precisar instrumentar os aplicativos individualmente.

Neste blog, mostramos como habilitar o rastreamento distribuído de solicitações para NGINX ou NGINX Plus (para resumir, nos referiremos apenas a NGINX Plus a partir de agora). Fornecemos instruções para dois serviços de rastreamento distribuídos ( rastreadores , na terminologia OpenTracing), Jaeger e Zipkin . (Para uma lista de outros rastreadores, consulte a documentação do OpenTracing .) Para ilustrar o tipo de informação fornecida pelos rastreadores, comparamos o processamento de solicitações antes e depois da ativação do cache do NGINX Plus.

Um rastreador tem dois componentes básicos:

  • Um agente que coleta dados de rastreamento de aplicativos em execução no host onde está sendo executado. No nosso caso, o “aplicativo” é o NGINX Plus e o agente é implementado como um plug-in.
  • Um servidor (também chamado de coletor ) que aceita dados de rastreamento de um ou mais agentes e os exibe em uma IU central. Você pode executar o servidor no host NGINX Plus ou em outro host, como você escolher.

Instalando um servidor Tracer

O primeiro passo é instalar e configurar o servidor para o rastreador de sua escolha. Estamos fornecendo instruções para Jaeger e Zipkin; adapte-as conforme necessário para outros rastreadores.

Instalando o Servidor Jaeger

Recomendamos o seguinte método para instalar o servidor Jaeger. Você também pode baixar imagens do Docker no URL especificado na Etapa 1.

  1. Navegue até a página de download do Jaeger e baixe o binário do Linux (no momento da escrita, jaeger-1.12.0-linux-amd64.tar ).

  2. Mova o binário para /usr/bin/jaeger (criando o diretório primeiro, se necessário) e execute-o.

    $ mkdir /usr/bin/jaeger $ mv jaeger-1.12.0-linux-amd64.tar /usr/bin/jaeger $ cd /usr/bin/jaeger $ tar xvzf jaeger-1.12.0-linux-amd64.tar.gz $ sudo rm -rf jaeger-1.12.0-linux-amd64.tar.gz $ cd jaeger-1.12.0-linux-amd64 $ ./jaeger-tudo-em-um
  3. Verifique se você consegue acessar a interface do usuário do Jaeger no seu navegador, em http:// Jaeger-server-IP-address :16686/ (16686 é a porta padrão para o servidor Jaeger).

Instalando o servidor Zipkin

  1. Baixe e execute uma imagem Docker do Zipkin (estamos usando a porta 9411, o padrão).

    $ docker run -d -p 9411:9411 openzipkin/zipkin
  2. Verifique se você consegue acessar a interface do usuário do Zipkin no seu navegador, em http:// Zipkin-server-IP-address :9411/ .

Instalando e configurando um plug-in Tracer

Execute estes comandos no host NGINX Plus para instalar o plug-in para Jaeger ou Zipkin.

Instalando o Jaeger Plug‑In

  1. Instale o plug-in Jaeger. O seguinte comando wget é para sistemas Linux x86‑64:

    $ cd /usr/local/lib $ wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so

    As instruções para construir o plug-in a partir do código-fonte estão disponíveis no GitHub .

  2. Crie um arquivo de configuração no formato JSON para o plug-in, chamado /etc/jaeger/jaeger-config.json , com o seguinte conteúdo. Estamos usando a porta padrão para o servidor Jaeger, 6831:

    { "nome_do_serviço": "nginx", "amostrador": { "tipo": "const", "parâmetro": 1}, "repórter": { "localAgentHostPort": " Endereço IP do servidor Jaeger : 6831" } }

    Para obter detalhes sobre o objeto sampler , consulte a documentação do Jaeger .

Instalando o plug-in Zipkin

  1. Instale o plug-in Zipkin. O seguinte comando wget é para sistemas Linux x86‑64:

    $ cd /usr/local/lib $ wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so
  2. Crie um arquivo de configuração no formato JSON para o plug-in, chamado /etc/zipkin/zipkin-config.json , com o seguinte conteúdo. Estamos usando a porta padrão para o servidor Zipkin, 9411:

    { "nome_do_serviço": "nginx", "host_do_coletor": " Endereço IP do servidor Zipkin ", "porta_do_coletor": 9411 }

    Para obter detalhes sobre os objetos de configuração, consulte o esquema JSON no GitHub .

Configurando o NGINX Plus

Execute estas instruções no host NGINX Plus.

  1. Instale o módulo NGINX OpenTracing de acordo com as instruções no Guia de administração do NGINX Plus .

  2. Adicione a seguinte diretiva load_module no contexto principal (nível superior) do arquivo de configuração principal do NGINX Plus ( /etc/nginx/nginx.conf ):

    load_module módulos/ngx_http_opentracing_module.so;
  3. Adicione as seguintes diretivas à configuração do NGINX Plus.

    Se você usar o esquema de configuração convencional , coloque as diretivas em um novo arquivo chamado /etc/nginx/conf.d/opentracing.conf . Verifique também se a seguinte diretiva include aparece no contexto http em /etc/nginx/nginx.conf :

    http {
    incluir /etc/nginx/conf.d/*.conf;
    }
    • A diretiva opentracing_load_tracer habilita o plug-in tracer. Descomente a diretiva para Jaeger ou Zipkin, conforme apropriado.
    • As diretivas opentracing_tag tornam as variáveis NGINX Plus disponíveis como tags OpenTracing que aparecem na interface do usuário do rastreador.
    • Para depurar a atividade do OpenTracing, descomente as diretivas log_format e access_log . Se você quiser substituir o log de acesso e o formato de log padrão do NGINX por este, descomente as diretivas e altere as três instâncias de “ opentracing ” para “ main “. Outra opção é registrar a atividade do OpenTracing apenas para o tráfego na porta 9001 – descomente as diretivas log_format e access_log e mova-as para o bloco server .
    • O bloco do servidor configura o OpenTracing para o aplicativo Ruby de exemplo descrito na próxima seção .
    # Carregar um rastreador de fornecedor#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so 
    # /etc/jaeger/jaeger-config.json;
    #opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
    # /etc/zipkin/zipkin-config.json;
    
    # Habilitar rastreamento para todas as solicitações
    opentracing on;
    
    # Definir tags adicionais que capturam o valor das variáveis NGINX Plus
    opentracing_tag bytes_sent $bytes_sent;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag request_time $request_time;
    opentracing_tag upstream_addr $upstream_addr;
    opentracing_tag upstream_bytes_received $upstream_bytes_received;
    opentracing_tag upstream_cache_status $upstream_cache_status;
    opentracing_tag upstream_connect_time $upstream_connect_time;
    opentracing_tag upstream_header_time $upstream_header_time;
    opentracing_tag upstream_queue_time $upstream_queue_time;
    opentracing_tag upstream_response_time $upstream_response_time;
    
    #descomentar para depuração
    # log_format opentracing '$remote_addr - $remote_user [$time_local] "$request" '
    # '$status $body_bytes_sent "$http_referer" '
    # '"$http_user_agent" "$http_x_forwarded_for" '
    # '"$host" sn="$server_name" '
    # 'rt=$request_time '
    # 'ua="$upstream_addr" us="$upstream_status" '
    # 'ut="$upstream_response_time" ul="$upstream_response_length" '
    # 'cs=$upstream_cache_status';
    #access_log /var/log/nginx/opentracing.log opentracing;
    
    servidor {
    ouvir 9001;
    
    location / {
    # O nome da operação usado para OpenTracing Spans assume como padrão o nome do
    # bloco 'location', mas descomente esta diretiva para personalizá-la.
    #opentracing_operation_name $uri;
    
    # Propaga o contexto Span ativo upstream, para que o rastreamento possa ser 
    # continuado pelo backend.
    opentracing_propagate_context;
    
    # Certifique-se de que seu aplicativo Ruby esteja escutando na porta 4567
    proxy_pass http://127.0.0.1:4567;
    }
    }
  4. Valide e recarregue a configuração do NGINX Plus:

    $ nginx -t $ nginx -s recarregar

Configurando o aplicativo Ruby de exemplo

Com o rastreador e a configuração do NGINX Plus em vigor, criamos um aplicativo Ruby de exemplo que mostra a aparência dos dados do OpenTracing. O aplicativo nos permite medir o quanto o cache do NGINX Plus melhora o tempo de resposta. Quando o aplicativo recebe uma solicitação como a seguinte solicitação HTTP GET para / , ele aguarda um período de tempo aleatório (entre 2 e 5 segundos) antes de responder.

$ curl http:// NGINX-Plus-IP-address :9001/
  1. Instalar e configurar Ruby e Sinatra (uma biblioteca de aplicativos web de software de código aberto e linguagem específica de domínio escrita em Ruby como uma alternativa a outras estruturas de aplicativos web Ruby).

  2. Crie um arquivo chamado app.rb com o seguinte conteúdo:

    #!/usr/bin/ruby
    
    require 'sinatra'
    
    get '/*' do
    out = "<h1>Aplicativo Ruby simples</h1>" + "\n"
    
    #Dorme um tempo aleatório entre 2s e 5s
    sleeping_time = rand(4)+2
    sleep(sleeping_time)
    puts "dormiu por: #{sleeping_time}s."
    out += '<p>algum texto de saída</p>' + "\n"
    
    return out
    end
  3. Crie app.rb executável e execute-o:

    $ chmod +x aplicativo.rb $ ./app.rb

Rastreando tempos de resposta sem cache

Usamos Jaeger e Zipkin para mostrar quanto tempo o NGINX Plus leva para responder a uma solicitação quando o cache não está habilitado. Para cada rastreador, enviamos cinco solicitações.

Saída do Jaeger sem cache

Aqui estão as cinco solicitações exibidas na interface do usuário do Jaeger (as mais recentes primeiro):

Aqui estão as mesmas informações no console do aplicativo Ruby:

- -> /dormiu para: 3s. 
127.0.0.1 - - [07/jun/2019: 10:50:46 +0000] "GET / HTTP/1.1" 200 49 3.0028
127.0.0.1 - - [07/jun/2019: 10:50:43 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 2s. 
127.0.0.1 - - [07/jun/2019: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018 
127.0.0.1 - - [07/jun/2019: 10:50:54 UTC] "GET / HTTP/1.0"1 200 49
- -> /
dormiu por: 3s. 
127.0.0.1 - - [07/jun/2019: 10:53:16 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [07/jun/2019: 10:53:13 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 4s.
127.0.0.1 - - [07/jun/2019: 10:54:03 +0000] "GET / HTTP/1.1" 200 49 4.0030 
127.0.0.1 - - [07/jun/2019: 10:53:59 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 3s.
127.0.0.1 - - [07/jun/2019: 10:54:11 +0000] "GET / HTTP/1.1" 200 49 3.0012
127.0.0.1 - - [07/jun/2019: 10:54:08 UTC] "OBTER / HTTP/1.0" 200 49

Na interface do usuário do Jaeger, clicamos na primeira solicitação (mais recente) para visualizar detalhes sobre ela, incluindo os valores das variáveis NGINX Plus que adicionamos como tags:

Saída do Zipkin sem cache

Aqui estão outras cinco solicitações na interface do usuário do Zipkin:

As mesmas informações no console do aplicativo Ruby:

- -> /dormiu para: 2s.
127.0.0.1 - - [07/jun/2019: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021 
127.0.0.1 - - [07/jun/2019: 10:31:16 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 3s.
127.0.0.1 - - [07/jun/2019: 10:31:50 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [07/jun/2019: 10:31:47 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 3s.
127.0.0.1 - - [07/jun/2019: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026 
127.0.0.1 - - [07/jun/2019: 10:32:05 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 3s.
127.0.0.1 - - [07/jun/2019: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015 
127.0.0.1 - - [07/jun/2019: 10:32:29 UTC] "GET / HTTP/1.0" 200 49
- -> /
dormiu por: 5s.
127.0.0.1 - - [07/jun/2019: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030 
127.0.0.1 - - [07/jun/2019: 10:32:47 UTC] "OBTER / HTTP/1.0" 200 49

Na interface do usuário do Zipkin, clicamos na primeira solicitação para visualizar detalhes sobre ela, incluindo os valores das variáveis do NGINX Plus que adicionamos como tags:

Rastreando tempos de resposta com cache

Configurando o cache do NGINX Plus

Habilitamos o cache adicionando diretivas no arquivo opentracing.conf que criamos em Configurando o NGINX Plus .

  1. No contexto http , adicione esta diretiva proxy_cache_path :

    proxy_cache_path /data/nginx/cache keys_zone=um:10m;
  2. No bloco do servidor , adicione as seguintes diretivas proxy_cache e proxy_cache_valid :

    proxy_cache um;
    proxy_cache_valid qualquer 1m;
  3. Valide e recarregue a configuração:

    $ nginx -t $ nginx -s recarregar

Saída do Jaeger com cache

Aqui está a interface do usuário do Jaeger após duas solicitações.

A primeira resposta (rotulada 13f69db ) levou 4 segundos. O NGINX Plus armazenou a resposta em cache e, quando a solicitação foi repetida cerca de 15 segundos depois, a resposta levou menos de 2 milissegundos (ms) porque veio do cache do NGINX Plus.

Analisar as duas solicitações em detalhes explica a diferença no tempo de resposta. Para a primeira solicitação, upstream_cache_status é MISS , o que significa que os dados solicitados não estavam no cache. O aplicativo Ruby adicionou um atraso de 4 segundos.

Para a segunda solicitação, upstream_cache_status é HIT . Como os dados vêm do cache, o aplicativo Ruby não pode adicionar um atraso, e o tempo de resposta é inferior a 2 ms. Os valores upstream_* vazios também indicam que o servidor upstream não estava envolvido nesta resposta.

Saída do Zipkin com cache

A exibição na interface do usuário do Zipkin para duas solicitações com cache habilitado mostra uma imagem semelhante:

E novamente, analisar as duas solicitações em detalhes explica a diferença no tempo de resposta. A resposta não é armazenada em cache para a primeira solicitação ( upstream_cache_status é MISS ) e o aplicativo Ruby (coincidentemente) adiciona o mesmo atraso de 4 segundos do exemplo do Jaeger.

A resposta foi armazenada em cache antes de fazermos a segunda solicitação, então upstream_cache_status é HIT .

Conclusão

O módulo NGINX OpenTracing permite o rastreamento de solicitações e respostas do NGINX Plus e fornece acesso às variáveis do NGINX Plus usando tags OpenTracing. Diferentes rastreadores também podem ser usados com este módulo.

Para mais detalhes sobre o módulo NGINX OpenTracing, visite o repositório do módulo NGINX OpenTracing no GitHub.

Para experimentar o OpenTracing com o NGINX Plus, comece hoje mesmo seu teste gratuito de 30 dias ou entre em contato conosco para discutir seus casos de uso .


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."