NGINX 和 NGINX Plus 的 OpenTracing

尽管微服务架构有很多好处,但它也带来了新的复杂性。其中之一是在处理请求时跟踪请求的挑战,数据在构成应用程序的所有微服务之间流动。为此,发明了一种称为分布式(请求)跟踪的新方法,而 OpenTracing 是一组 API 规范和标准,旨在指导分布式跟踪工具的设计和实现。

在 NGINX Plus Release 18 (R18) 中,我们将 NGINX OpenTracing 模块添加到我们的动态模块存储库中(几年前它已在 GitHub 上作为第三方模块提供)。 NGINX OpenTracing 模块的一大优势是,通过检测 NGINX 和 NGINX Plus 进行分布式跟踪,您可以获得每个代理应用程序的跟踪数据,而无需单独检测应用程序。

在本博客中,我们展示了如何启用 NGINX 或 NGINX Plus 请求的分布式跟踪(例如为简洁起见,从现在开始我们将仅提及 NGINX Plus)。我们提供了两种分布式跟踪服务(OpenTracing 术语中的跟踪器)Jaeger 和 Zipkin 的说明。 (有关其他跟踪器的列表,请参阅 OpenTracing 文档。)为了说明跟踪器提供的信息类型,我们比较了启用 NGINX Plus 缓存之前和之后的请求处理。

跟踪器有两个基本组件:

  • 从运行它的主机上运行的应用程序收集跟踪数据的代理。在我们的例子中,“应用程序”是 NGINX Plus,代理作为插件实现。
  • 一种服务器(也称为收集器),它接受来自一个或多个代理的跟踪数据并将其显示在中央 UI 中。您可以根据自己的选择在 NGINX Plus 主机或其他主机上运行服务器。

安装跟踪服务器

第一步是为您选择的跟踪器安装和配置服务器。我们正在为 Jaeger 和 Zipkin 提供说明;根据其他跟踪器的需要调整它们。

安装 Jaeger 服务器

我们推荐使用以下方法安装 Jaeger 服务器。您还可以通过步骤 1 中指定的 URL 下载 Docker 映像。

  • 导航到 Jaeger 下载页面并下载 Linux 二进制文件(在撰写本文时为 jaeger-1.12.0-linux-amd64.tar)。

  • 将二进制文件移至 /usr/bin/jaeger(如有必要,请先创建该目录),然后运行它。

    $ 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 多合一

  • 验证您是否可以在浏览器中访问 Jaeger UI,网址为 http://Jaeger-server-IP-address:16686/(16686 是 Jaeger 服务器的默认端口)。

  • 安装 Zipkin 服务器

  • 下载并运行 Zipkin 的 Docker 映像(我们使用默认端口 9411)。

    $ docker run -d -p 9411:9411 openzipkin/zipkin

  • 验证您是否可以在浏览器中访问 Zipkin UI,网址为:http://Zipkin-server-IP-address:9411/。

  • 安装和配置 Tracer 插件

    在 NGINX Plus 主机上运行这些命令来安装 Jaeger 或 Zipkin 的插件。

    安装 Jaeger 插件

  • 安装 Jaeger 插件。以下 wget 命令适用于 x86-64 Linux 系统:

    $ 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

    GitHub 上提供了从源代码构建插件的说明。

  • 为插件创建一个 JSON 格式的配置文件,名为 /etc/jaeger/jaeger-config.json,其中包含 t他以下内容。我们使用 Jaeger 服务器的默认端口 6831:

    {
    “服务名称”:“nginx”,
    “采样器”:{
    “类型”:“常量”,
    “参数”:1
    },
    “记者”:{
    “localAgentHostPort”: “Jaeger 服务器 IP 地址:6831”
    }
    }

    有关采样器对象的详细信息,请参阅 Jaeger 文档。

  • 安装 Zipkin 插件

  • 安装 Zipkin 插件。以下 wget 命令适用于 x86-64 Linux 系统:

    $ 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

  • 为插件创建一个 JSON 格式的配置文件,名为 /etc/zipkin/zipkin-config.json,其中包含以下内容。我们使用 Zipkin 服务器的默认端口 9411:

    {
    “服务名称”:“nginx”,
    “collector_host”: “Zipkin 服务器-IP地址”,
    “收集器端口”:9411
    }

    有关配置对象的详细信息,请参阅 GitHub 上的 JSON 架构。

  • 配置 NGINX Plus

    在 NGINX Plus 主机上执行这些说明。

  • 按照 NGINX Plus 管理指南中的说明安装 NGINX OpenTracing 模块。

  • 在主 NGINX Plus 配置文件 (/etc/nginx/nginx.conf) 的主(顶级)上下文中添加以下 load_module 指令:

    load_module 模块/ngx_http_opentracing_module.so;

  • 将以下指令添加到 NGINX Plus 配置中。

    如果您使用传统的配置方案,请将指令放入名为 /etc/nginx/conf.d/opentracing.conf 的新文件中。还要验证以下 include 指令是否出现在 /etc/nginx/nginx.conf 的 http 上下文中:

    http{
    包括/etc/nginx/conf.d/*.conf;
    }

    • opentracing_load_tracer 指令启用跟踪器插件。根据需要取消 Jaeger 或 Zipkin 指令的注释。
    • opentracing_tag 指令使 NGINX Plus 变量可作为 OpenTracing 标记显示在跟踪器 UI 中。
    • 要调试 OpenTracing 活动,请取消注释 log_format 和 access_log 指令。如果您想用此替换默认的 NGINX 访问日志和日志格式,请取消注释指令,然后将“opentracing”的三个实例更改为“main”。另一种选择是仅记录端口 9001 上流量的 OpenTracing 活动 – 取消注释 log_format 和 access_log 指令并将它们移至服务器块中。
    • 服务器块为下一节中描述的示例 Ruby 应用程序设置 OpenTracing。

    # 加载供应商跟踪器
    #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;

    # 为所有请求启用跟踪
    打开跟踪;

    # 设置捕获 NGINX Plus 变量值的附加标签
    opentracing_tag bytes_sent $bytes_sent;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag request_time $request_time;
    opentracing_tag upload_addr $upstream_addr;
    opentracing_tag upload_bytes_received $upstream_bytes_received;
    opentracing_tag upload_cache_status $upstream_cache_status;
    opentracing_tag upload_connect_time $upstream_connect_time;
    opentracing_tag upload_header_time $upstream_header_time;
    opentracing_tag upload_queue_time $upstream_queue_time;
    opentracing_tag upload_response_time $upstream_response_time;

    #取消注释以进行调试
    # 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;

    服务器 {
    听9001;

    地点 / {
    # OpenTracing Spans 使用的操作名称默认为
    # ‘location’ 块,但取消注释该指令以自定义它。
    #opentracing_operation_name $uri;

    # 将活动的 Span 上下文传播到上游,以便跟踪
    # 由后端继续。
    opentracing_propagate_context;

    # 确保您的 Ruby 应用程序正在侦听端口 4567
    proxy_pass http://127.0.0.1:4567;
    }
    }

  • 验证并重新加载 NGINX Plus 配置:

    $ nginx-t
    $nginx -s 重新加载

  • 设置示例 Ruby 应用

    跟踪器和 NGINX Plus 配置到位后,我们创建一个示例 Ruby 应用程序来显示 OpenTracing 数据的样子。该应用程序可让我们衡量 NGINX Plus 缓存对响应时间的改善程度。当应用收到类似于以下 HTTP GET 请求 / 的请求时,它会在响应之前等待一段随机时间(2 到 5 秒之间)。

    $curl http://NGINX-Plus-IP-地址:9001/

  • 安装并设置 Ruby 和 Sinatra(开源软件 Web 应用程序库和用 Ruby 编写的领域特定语言,作为其他 Ruby Web 应用程序框架的替代方案)。

  • 创建一个名为 app.rb 的文件,其中包含以下内容:

    #!/usr/bin/ruby

    需要“西纳特拉”

    得到 ‘/*’ 做
    out = “

    Ruby 简单应用

    ” + “\n”

    #睡眠2秒到5秒之间的随机时间
    睡眠时间 = 兰特(4)+2
    睡眠(睡眠时间)
    puts“睡了:#{sleeping_time}s。”
    out += ‘

    一些输出文本

    ‘ + “\n”

    返回
    结尾

  • 使 app.rb 可执行并运行它:

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

  • 在没有缓存的情况下跟踪响应时间

    我们使用 Jaeger 和 Zipkin 来显示在未启用缓存的情况下 NGINX Plus 响应请求所需的时间。对于每个跟踪器,我们发送五个请求。

    Jaeger 的输出(不带缓存)

    以下是 Jaeger UI 中显示的五个请求(最新的在前):

    以下是 Ruby 应用控制台上的相同信息:

    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:50:46 +0000]“GET / HTTP/1.1”200 49 3.0028
    127.0.0.1 – – [2019 年 6 月 7 日:10:50:43 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:2秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:50:56 +0000]“GET / HTTP/1.1”200 49 2.0018
    127.0.0.1 – – [2019年6月7日: 10:50:54 UTC] “GET / HTTP/1.0”1 200 49
    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日: 10:53:16+0000]“获取/HTTP/1.1”200 49 3.0029
    127.0.0.1 – – [2019 年 6 月 7 日:10:53:13 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:4秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:54:03 +0000]“GET / HTTP/1.1”200 49 4.0030
    127.0.0.1 – – [2019 年 6 月 7 日:10:53:59 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:54:11 +0000]“GET / HTTP/1.1”200 49 3.0012
    127.0.0.1 – – [2019 年 6 月 7 日:10:54:08 UTC]“GET / HTTP/1.0”200 49

    在 Jaeger UI 中,我们单击第一个(最近的)请求以查看其详细信息,包括我们添加为标签的 NGINX Plus 变量的值:

    没有缓存的 Zipkin 输出

    以下是 Zipkin UI 中的另外五个请求:

    Ruby 应用程序控制台上的相同信息:

    – -> /
    睡了:2秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:31:18 +0000]“GET / HTTP/1.1”200 49 2.0021
    127.0.0.1 – – [2019 年 6 月 7 日:10:31:16 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日: 10:31:50 +0000] “GET/HTTP/1.1″ 200 49 3.0029
    127.0.0.1 – – [2019 年 6 月 7 日:10:31:47 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:08 +0000]“GET / HTTP/1.1”200 49 3.0026
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:05 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:3秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:32 +0000]“GET / HTTP/1.1”200 49 3.0015
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:29 UTC]“GET / HTTP/1.0”200 49
    – -> /
    睡了:5秒。
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:52 +0000]“GET / HTTP/1.1”200 49 5.0030
    127.0.0.1 – – [2019 年 6 月 7 日:10:32:47 UTC]“GET / HTTP/1.0”200 49

    在 Zipkin UI 中,我们单击第一个请求以查看其详细信息,包括我们添加为标签的 NGINX Plus 变量的值:

    使用缓存跟踪响应时间

    配置 NGINX Plus 缓存

    我们通过在配置 NGINX Plus 中创建的 opentracing.conf 文件中添加指令来启用缓存。

  • 在http上下文中,添加这个proxy_cache_path指令:

    proxy_cache_path /data/nginx/cachekeys_zone=one:10m;

  • 在服务器块中,添加以下 proxy_cache 和 proxy_cache_valid 指令:

    proxy_cache一;
    proxy_cache_valid 任意 1m;

  • 验证并重新加载配置:

    $ nginx-t
    $ nginx -s 重新加载

  • Jaeger 的缓存输出

    这是两次请求后的 Jaeger UI。

    第一个响应(标记为 13f69db)花了 4 秒。 NGINX Plus 缓存了响应,当大约 15 秒后重复请求时,响应时间不到 2 毫秒 (ms),因为它来自 NGINX Plus 缓存。

    详细查看这两个请求可以解释响应时间的差异。对于第一个请求,upstream_cache_status为MISS,表示请求的数据不在缓存中。 Ruby 应用添加了 4 秒的延迟。

    对于第二个请求,upstream_cache_status 为 HIT。是由于数据来自缓存,Ruby 应用无法添加延迟,响应时间低于 2 毫秒。空的 upload_* 值还表明上游服务器未参与此响应。

    带有缓存的 Zipkin 输出

    启用缓存的两个请求在 Zipkin UI 中的显示描绘了相似的画面:

    再次详细查看这两个请求可以解释响应时间的差异。第一个请求的响应不会被缓存(upstream_cache_status 为 MISS),并且 Ruby 应用程序(巧合)添加了与 Jaeger 示例中相同的 4 秒延迟。

    在我们发出第二个请求之前,响应已被缓存,因此 upload_cache_status 为 HIT。

    结论

    NGINX OpenTracing 模块可以跟踪 NGINX Plus 请求和响应,并使用 OpenTracing 标签提供对 NGINX Plus 变量的访问。该模块还可以使用不同的示踪剂e.

    有关 NGINX OpenTracing 模块的更多详细信息,请访问 GitHub 上的 NGINX OpenTracing 模块存储库。

    要尝试使用 NGINX Plus 进行 OpenTracing,请立即开始 30 天免费试用,或联系我们讨论您的使用案例。


    评论

    发表回复

    您的电子邮箱地址不会被公开。 必填项已用 * 标注