Apache自身耗时用%D(微秒),Java真实耗时需应用通过X-Response-Time响应头传递并用%{X-Response-Time}o捕获,二者共存可定位链路瓶颈。

Apache 的 mod_log_config 本身只能记录它自己处理请求的耗时(比如接收请求到发出响应头的时间),无法直接感知后端 Java 应用的内部执行时间,更无法测量“请求发给后端 → 后端处理 → 响应返回 Apache”这个完整往返过程(即后端响应往返时延,RTT)。要同时记录这两类时间,必须分层配合:Apache 记自身耗时,Java 应用主动上报处理耗时,再由 Apache 日志捕获并共存。
记录 Apache 自身处理耗时:%D 是核心字段
使用 %D 可记录 Apache 从收到请求第一个字节,到发送完响应头所经过的微秒数。这是最准确、开销最小的服务器层耗时指标。
- 在
httpd.conf或虚拟主机配置中定义日志格式:LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" apache_time - 启用该格式:
CustomLog logs/access_log apache_time - 日志示例末尾数字为微秒:
... "GET /api/data HTTP/1.1" 200 312 "-" "curl/7.68.0" 42891→ 约 42.9 ms - 注意:
%T是秒级整数(截断小数),精度不足;%{msec}t是时间戳毫秒部分,不是耗时,别混淆
记录后端 Java 真实处理耗时:靠响应头传递
Apache 不知道 Tomcat 或 Spring Boot 里代码跑了多久。必须让 Java 应用在响应前计算并写入一个标准响应头,例如 X-Response-Time 或 X-Process-Time(推荐统一用前者)。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- Spring Boot 过滤器示例:
long start = System.currentTimeMillis();<br>chain.doFilter(request, response);<br>long duration = System.currentTimeMillis() - start;<br>response.setHeader("X-Response-Time", String.valueOf(duration)); - 确保头名一致且不被中间件吞掉(如 Nginx 前置需配
proxy_pass_request_headers on) - Apache 配置中用
%{X-Response-Time}o捕获(小写o表示 output headers):LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Response-Time}o" java_rtt - 若日志中该位置显示
-或0,大概率是 Java 没设头、头名拼错、或被代理/压缩模块拦截
区分两类时间的实际意义
%D 和 %{X-Response-Time}o 数值通常不相等,差值能暴露链路瓶颈:
- 若
%D ≈ %{X-Response-Time}o:说明耗时主要在 Java 层,Apache 开销可忽略 - 若
%D ≫ %{X-Response-Time}o:可能是 Apache 层 SSL 解密、gzip 压缩、重写规则、或 mod_proxy 转发延迟高 - 若
%D < %{X-Response-Time}o(极少见):多线程下计时变量被复用,或 Java 写头逻辑有误 - 若两者都很大但接近,而 HAProxy 或 Nginx 日志中
%Tr更大:说明网络传输或后端连接池等待拖慢了整体 RTT
注意事项与常见失效原因
这两个字段能共存,但依赖环境稳定:
-
%{X-Response-Time}o在 Apache 2.2.15+ 才稳定支持;旧版需改用mod_lua+ notes 方式 - 确认
mod_headers已加载(LoadModule headers_module modules/mod_headers.so),否则响应头可能无法透传 - 用了
mod_deflate或流式响应(SSE)时,%D仍准,但%{X-Response-Time}o必须在响应体开始写出前设置,否则可能丢失 - 日志轮转工具要兼容字段长度:
%D最多 7 位(约 24 天最大值),X-Response-Time一般不超过 6 位,单行别超长

















