我在几个上游应用服务器前使用 nginx 作为负载均衡器,我想设置一个跟踪 ID 以用于将请求与应用服务器日志相关联。在 Nginx 中做到这一点的最佳方法是什么,是否有一个好的 3rd 方模块呢?
否则,一种非常简单的方法是将其基于时间戳(如果不够精确,可能加上随机数)并将其设置为请求的额外标头,但我在文档中看到的唯一 set_header 命令是用于设置响应头。
我在几个上游应用服务器前使用 nginx 作为负载均衡器,我想设置一个跟踪 ID 以用于将请求与应用服务器日志相关联。在 Nginx 中做到这一点的最佳方法是什么,是否有一个好的 3rd 方模块呢?
否则,一种非常简单的方法是将其基于时间戳(如果不够精确,可能加上随机数)并将其设置为请求的额外标头,但我在文档中看到的唯一 set_header 命令是用于设置响应头。
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中的参考资料
在大多数情况下,您不需要自定义模块,您可以简单地设置一个包含 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。
老问题,新答案适用于 nginx 版本1.3.8
,1.2.5
及以上。
您可以使用$connection
和$connection_requests
now 的组合。只需在块中定义您自己的变量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 时间戳,以秒为单位,以毫秒为单位(浮点数)。
在我们的生产环境中,我们确实有一个像这样的自定义模块。它可以生成一个唯一的跟踪 id,然后将其推送到发送到上游服务器的 http 标头中。上游服务器会检查是否设置了某个字段,它会获取该值并将其写入 access_log,这样我们就可以跟踪请求。
而且我发现第 3 方模块看起来一样:nginx-operationid,希望对您有所帮助。