38

我在几个上游应用服务器前使用 nginx 作为负载均衡器,我想设置一个跟踪 ID 以用于将请求与应用服务器日志相关联。在 Nginx 中做到这一点的最佳方法是什么,是否有一个好的 3rd 方模块呢?

否则,一种非常简单的方法是将其基于时间戳(如果不够精确,可能加上随机数)并将其设置为请求的额外标头,但我在文档中看到的唯一 set_header 命令是用于设置响应头。

4

4 回答 4

102

nginx 1.11.0 添加了$request_id作为唯一标识符的新变量,因此您可以执行以下操作:

   location / {
      proxy_pass http://upstream;
      proxy_set_header X-Request-Id $request_id;
   }

请参阅http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_id中的参考资料

于 2016-07-19T00:34:32.220 回答
33

在大多数情况下,您不需要自定义模块,您可以简单地设置一个包含 http_core_module 的嵌入变量组合的标题,这(很可能)是唯一的。例子:

  location / {
      proxy_pass http://upstream;
      proxy_set_header X-Request-Id $pid-$msec-$remote_addr-$request_length;
  }

这将产生一个请求 ID,如“31725-1406109429.299-127.0.0.1-1227”,并且应该“足够独特”以用作跟踪 ID。

于 2014-07-23T12:33:48.853 回答
12

老问题,新答案适用于 nginx 版本1.3.81.2.5及以上。

您可以使用$connection$connection_requestsnow 的组合。只需在块中定义您自己的变量server

server {
    ...
    set  $trace_id  $connection-$connection_requests;
    ...
}

除非服务器重新启动,否则此 id 在 nginx 中将是唯一的。

$connection-连接序列号。这是 nginx 为每个连接分配的唯一编号。如果在单个连接上接收到多个请求,它们都将具有相同的连接序列号。当主 nginx 进程终止时,序列号会重置,因此它们在很长一段时间内不会唯一。

$connection_requests- 通过这个发出的请求数 $connection

然后,在您的location块中,设置实际的跟踪 ID:

location / {
    ...
    proxy_set_header X-Request-Id $trace_id;
    ...
}

奖励:即使$trace_id在服务器重新启动后也保持唯一:

set  $trace_id  $connection-$connection_requests-$msec;

$msec- 当前的 unix 时间戳,以秒为单位,以毫秒为单位(浮点数)。

于 2018-07-21T14:20:12.447 回答
0

在我们的生产环境中,我们确实有一个像这样的自定义模块。它可以生成一个唯一的跟踪 id,然后将其推送到发送到上游服务器的 http 标头中。上游服务器会检查是否设置了某个字段,它会获取该值并将其写入 access_log,这样我们就可以跟踪请求。

而且我发现第 3 方模块看起来一样:nginx-operationid,希望对您有所帮助。

于 2013-07-19T16:04:29.920 回答