N33_烟灰 2021-09-09 11:08 采纳率: 0%
浏览 392
已结题

nginx 反向代理 $upstream_header_time 耗时时间问题($upstream_connect_time时间短)

1、环境
OS 版本和内核: CentOS Linux release 7.9.2009 3.10.0-1160.el7.x86_64
nginx 版本: nginx-1.14.2 (社区版)
upstream server(tomcat) 版本: apache tomcat 8.0.53
JDK 版本: Oracle jdk1.8.0_144

nginx 对客户端有启用保持连接;
nginx 与 upstream server 有启用保持连接;

HTTP/1.1

2、nginx 日志格式和tomcat日志格式

(1) nginx 日志格式
'$remote_addr - $remote_user [$time_iso8601] '
' "$request" $status $body_bytes_sent $bytes_sent '
' $request_trace_id '
' ["$upstream_addr" "$upstream_status" "$upstream_bytes_received" "$upstream_response_length" "$upstream_cache_status" '
' "$upstream_response_time" "$upstream_connect_time" "$upstream_header_time"] '
' "$request_time" "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$ssl_protocol"';

自定义的$request_trace_id:

#trace.setting
set $request_trace_id $http_x_request_id;
if ( $request_trace_id = '' ) {
set $request_trace_id $pid-$connection-$bytes_sent-$msec;
}

(2) tomcat 日志格式
"[%{Y-M-d H:m:s.S+z}t] real_ip:%{X-Real-IP}i remote:%h requestid:%{X-Request-ID}i first_line:"%r" status:%s bytes:%b cost:%Dms commit_time:%Fms Agent:"%{User-Agent}i" %{Connection}i %{Connection}o %{Keep-Alive}i %{Keep-Alive}o"

3、有问题的日志(nginx 和 tomcat 日志)
(1) nginx 日志
192.168.26.73 - cgpadmin [2021-09-09T09:58:23+08:00] "POST /cgp2-oauth/oauth/check_token HTTP/1.1" 200 12983 13364 6462-1025729-0-1631152697.976 ["127.0.0.1:8801" "200" "13353" "12991" "-" "5.026" "0.000" "5.026"] "5.026" "-" "Java/1.8.0_144" "-" "-"
1631152697.976 时间戳转换成时间是:
2021-09-09 09:58:17.976

(2) tomcat 日志
[2021-9-9 9:58:17.993+CST] real_ip:192.168.26.73 remote:127.0.0.1 requestid:6462-1025729-0-1631152697.976 first_line:"POST /cgp2-oauth/oauth/check_token HTTP/1.1" status:200 bytes:12991 cost:17ms commit_time:16ms Agent:"Java/1.8.0_144" - - - -

4、自己的分析和判断,以及提出问题
nginx 的几个时间:

  • 变量
    $request_time 5.026 秒
    $upstream_response_time 5.026 秒
    $upstream_header_time 0.000 秒
    $upstream_connect_time 5.026 秒

  • 日志时间
    nginx 开始处理 proxy_pass 转发的时刻: 2021-09-09 09:58:17.976
    nginx 最后发完响应报文给客户端的时间(只管发完,不管客户接收是否完成): 2021-09-09T09:58:23

tomcat 的几个时间:

  • 属性
    %D 17 毫秒
    %F 16 毫秒

  • 日志时间
    tomcat 处理完成(把响应报文发完给nginx的时刻,只管发完,不管nginx 接收是否完成): 2021-9-9 9:58:17.993

分析出问题的阶段:
nginx 处理总耗时时长($request_time)是因为 upstream 处理耗时时长($upstream_response_time);
在upstream 处理中,nginx先准备好了请求报文的内容,然后与tomcat之间建立连接,这个连接时长很短(我这里节选的日志是
0,可能是因为保持连接的缘故,我看了其他连接,也都是很短有不为0的情况),所以$upstream_header_time 基本可以确认大概
是 nginx与tomcat连接后"开始发请求报文到tomcat","tomcat接收"(我理解可能会有队列,tomcat接收),"tomcat处理","tomcat返回
响应报文","nginx收到响应报文头的第一个字节" 这个过程之间的耗时时间长,开始分析是哪一段的问题

nginx 完成时刻记录时间是 9:58:23 (这里不知道毫秒,因为我用的是默认的变量),而 upstream 总耗时时长是 5.026秒,tomcat
返回报文的时刻是 9:58:17.993,9:58:23 减去 5.026秒大概就是 9:58:18左右和tomcat返回报文时刻差不多,说明 nginx 和客户端之间
的耗时时长不长,基本可以确认nginx向tomcat建立连接时刻也差不多是 9:58:18 左右,我们刚好有 $request_trace_id,这个时刻
即为nginx开始处理反向代理时刻,它是2021-09-09 09:58:17.976,基本可以印证我们的猜想。而 tomcat 反向报文时刻是 9:58:17.993,
它减去tomcat内部自己处理时长(%D 17毫秒),得到tomcat开始处理请求的时刻是 9:58:17.976这个时刻和我们 $request_trace_id 09:58:17.976
基本是一样的,说明nginx开始发请求报文到tomcat到tomcat从池中分类线程处理耗时基本没有。所以upstream处理时间5耗时是在 tomcat准备响应报文后,
把响应报文发给nginx,nginx收到响应报文头的第一个字节的时间(走127.0.0.1基本没有网络问题,而且监控也没有看到。
是否nginx也有队列?不是upstrem 是基于epoll实现的事件回调吗,)

这边系统有时候有前置的问题有时候有后置的问题(本例是后置的问题),请大家给点思路,我好推进这个问题,谢谢!

5、参考文档

Using NGINX Logging for Application Performance Monitoring Learn how to use the logging facility in NGINX and NGINX Plus for application performance monitoring (APM) https://www.nginx.com/blog/using-nginx-logging-for-application-performance-monitoring/
java - Tomcat log: what's the difference between %D and %F - Stack Overflow I am using tomcat log to log the access info and the definitions of %D and %F in official doc is %D - Time taken to process the request, in millis %F - Time taken to commit the response, in mill... https://stackoverflow.com/questions/42685694/tomcat-log-whats-the-difference-between-d-and-f
Module ngx_http_upstream_module http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables
Apache Tomcat 8 Configuration Reference (8.0.53) - The Valve Component https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html
掘金 https://juejin.cn/post/6844903887757901832
nginx upstream模块完整逻辑源码分析 - 云+社区 - 腾讯云 1.启动upstream。 2.连接上游服务器。 3.向上游发送请求。 4.接收上游响应(包头/包体)。 5.结束请求。 https://cloud.tencent.com/developer/article/1778734

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 9月17日
    • 创建了问题 9月9日

    悬赏问题

    • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
    • ¥20 怎么用dlib库的算法识别小麦病虫害
    • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
    • ¥15 java写代码遇到问题,求帮助
    • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
    • ¥15 有了解d3和topogram.js库的吗?有偿请教
    • ¥100 任意维数的K均值聚类
    • ¥15 stamps做sbas-insar,时序沉降图怎么画
    • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
    • ¥15 关于#Java#的问题,如何解决?