页面慢、接口超时,后端日志翻完还是找不到原因——问题多半卡在最前面那台 Nginx:转发成功没有、花了多久,日志里一概没有。
- 看不清:入口耗时、转发成败,传统日志对不上
- 串不上:Nginx 和后端各记各的,拼不成一条链路
- 不敢动:存量 Nginx,怕加模块影响现网
- 不想改码:业务侧希望零侵入,最好挂上就能报
做法很简单:Nginx 装 OTel 模块,Java 挂官方探针,都报到 DataBuff —— 一次请求就能看到 Nginx → Java → Redis 完整瀑布。
DataBuff 是开源的 AI Native OpenTelemetry APM:指标、链路、日志和 AI 排障放在一起,原生收 OTLP,Nginx / Java 报上来就能拼成一条 Trace。
GitHub:https://github.com/databufflabs/databuff
整体就这样:各记各的 Span,带同一个 TraceID 上报,平台拼成瀑布。业务代码一行不用改。
先准备好能收 OTLP 的 DataBuff(4317 gRPC / 4318 HTTP)。下面命令在装 Nginx、Java 的机器上执行;DataBuff 可以是同机或内网另一台。
| 方式 | 场景 | 怎么做 |
|---|---|---|
| 方式一 | 全新 / 容器 | 用 nginx:1.27-alpine-otel,模块内置,docker 挂配置启动 |
| 方式二 | 存量 Nginx | 装 nginx-module-otel → 写 conf → nginx -t → nginx -s reload |
两条路的 OTel 指令一样。模块要求 Nginx 1.21+;更旧就走方式一,和宿主机旧 Nginx 互不影响。
共用:完整 nginx.conf(存成文件,地址换成你的 DataBuff / Java;同机可写 127.0.0.1):
load_module /usr/lib/nginx/modules/ngx_otel_module.so;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 上报到 DataBuff:填 DataBuff 所在机器的 IP,走 gRPC 4317 口
otel_exporter {
endpoint <DataBuff机器IP>:4317;
interval 5s;
}
otel_service_name nginx-otel-demo;
# 关键一行:把 traceparent 透传给后端,否则链路会断
otel_trace_context propagate;
server {
listen 80;
otel_trace on;
location / {
# 反代到 Java 服务
proxy_pass http://<Java服务IP>:18091;
}
}
}
方式一 · 官方 OTel 镜像
镜像里已有模块,挂上刚写的 conf 启动即可:
docker run -d --name nginx-otel \ -p 8090:80 \ -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx:1.27-alpine-otel
改配置后:
docker cp /path/to/nginx.conf nginx-otel:/etc/nginx/nginx.conf docker exec nginx-otel nginx -t docker exec nginx-otel nginx -s reload
方式二 · 存量 Nginx 加装模块
先看版本(要 1.21+):
nginx -v
按系统装官方模块(装完可用 ls /usr/lib/nginx/modules/ngx_otel_module.so 确认):
# Alpine apk add --repository https://nginx.org/packages/mainline/alpine/v3.21/main nginx-module-otel # CentOS / RHEL(先配 nginx.org 官方 yum 源) yum install nginx-module-otel # Debian / Ubuntu(先配 nginx.org 官方 apt 源) apt install nginx-module-otel
把上面那份完整 conf 写到 /etc/nginx/nginx.conf(或在原 conf 顶部加 load_module,http 块加 otel_*,server 块加 otel_trace on)。然后先测配置、再热加载(不中断现有请求):
nginx -t # 先测配置对不对 nginx -s reload # 热加载,不用重启进程
Java 侧 · 挂探针
下载官方 opentelemetry-javaagent.jar,启动时加 JVM 参数。业务代码不用改。Java 走 HTTP 4318,Nginx 走 gRPC 4317,进同一个 DataBuff:
java -javaagent:opentelemetry-javaagent.jar \ -Dotel.service.name=java-redis-demo \ -Dotel.exporter.otlp.endpoint=http://<DataBuff机器IP>:4318 \ -jar your-app.jar
打流量,看瀑布
curl http://你的机器IP:8090/hello
打几次,等约 30 秒(批量导出有延迟),打开 DataBuff「链路追踪」,勾选 nginx-otel-demo,点开任意一条看完整瀑布。
最容易踩的坑:漏写 otel_trace_context propagate;。模块默认不往下游传 TraceID,Nginx 和 Java 会变成两条互不相干的 Trace。加上立刻串成一条。改完记得再 nginx -t && nginx -s reload(容器则 docker exec … nginx -s reload)。
- 版本太旧? 走方式一官方镜像,和宿主机旧 Nginx 互不影响。
- 要改 Java 代码吗? 不用。挂官方 javaagent,HttpServer / Jedis 自动插桩。
- 加模块影响现网?
nginx -t通过后nginx -s reload热加载即可。 - 建议路径 测试环境先方式一跑通,存量再方式二加装。