必须使用 skywalking-nginx-lua,因为 nginx 是 c 编写、不支持 jvm 字节码增强,而该官方 lua 探针通过 init_worker_by_lua_block 和 log_by_lua_block 等钩子埋点,生成符合 skywalking v3 协议的 trace segment 并上报,实现与后端 java 服务链路自动拼接。

要让 Nginx(或 OpenResty)真正成为云原生全链路监控的一环,关键不是“加个插件就完事”,而是让它的请求入口行为与后端服务在 SkyWalking 中形成可串联的调用链。Nginx 本身无 Java Agent 支持,必须借助 skywalking-nginx-lua 这一官方 Lua 实现的轻量级探针,才能将网关层纳入分布式追踪体系。
为什么必须用 skywalking-nginx-lua?
Nginx 是 C 编写的高性能服务器,不支持 JVM 类自动字节码增强。SkyWalking 的 Java/.NET/Go Agent 都无法直接注入。而 skywalking-nginx-lua 是 Apache SkyWalking 官方维护的 Lua 模块,它利用 OpenResty/Nginx 的 init_worker_by_lua_block、log_by_lua_block 等生命周期钩子,在请求进入、转发、响应、日志落盘等关键节点埋点,生成符合 SkyWalking v3 协议的 trace segment 并上报。
- 它不依赖外部进程或代理,零额外资源开销(仅共享内存 + 定时器)
- 支持跨服务透传 trace ID(通过
sw8或traceparent头) - 能捕获客户端 IP、URI、HTTP 方法、状态码、响应耗时、上游地址等核心指标
- 与后端 Java 服务的 SkyWalking Agent 自动拼接成一条完整链路(如:Nginx → Spring Cloud Gateway → User Service → MySQL)
核心配置要点(OpenResty 场景)
以下是最简可用且生产推荐的配置片段,需写入 nginx.conf 的 http 块中:
-
Lua 路径声明:
lua_package_path "/path/to/skywalking-nginx-lua/lib/skywalking/?.lua;;"; -
共享内存区(用于缓存 service 元数据和 trace 数据):
lua_shared_dict tracing_buffer 100m; -
服务身份注册(必须在 init_worker 阶段设置):
init_worker_by_lua_block { local meta = ngx.shared.tracing_buffer meta:set('serviceName', 'api-gateway') meta:set('serviceInstanceName', 'gateway-01') require("client"):startBackendTimer("http://skywalking-oap:12800") } -
请求链路织入(建议放在 server 或 location 块):
access_by_lua_block { require("tracing").start() } log_by_lua_block { require("tracing").finish() }
注意:http://skywalking-oap:12800 是 SkyWalking OAP Server 的 HTTP 接收端口(非 gRPC 的 11800),确保网络可达;服务名应与后端 Java 应用的 agent.service_name 语义一致,便于 UI 关联。
如何验证链路真正贯通?
配置生效后,发起一次请求(如 curl -H "sw8:1-MQ==..." http://your-nginx/health),然后登录 SkyWalking UI 查看:
- 左侧「服务列表」中应出现你配置的
serviceName(如api-gateway) - 点击该服务 → 「拓扑图」里能看到它作为入口节点,连向下游 Java 服务
- 点击任意一个调用记录 → 「追踪」页签中,第一段 span 的
peer字段为client,component显示nginx-lua,且span.kind为Entry - 整个 trace 中,所有 span 的
traceId完全一致,且包含从 Nginx 到数据库的全部层级
若只看到 Java 服务而没有 Nginx,常见原因有:Lua 路径错误、shared_dict 名称不匹配、OAP 地址不通、未启用 access_by_lua_block 和 log_by_lua_block、或后端服务未正确透传 header。
进阶:适配 nginx-ingress-controller 或 Docker 场景
在 Kubernetes 中,若使用 nginx-ingress-controller,不能直接改其二进制,需定制 nginx.tmpl 模板:
- 将
skywalking-nginx-lua文件挂载进容器的/etc/nginx/lua/目录 - 通过
controller-configmap注入环境变量:SW_SERVICE_NAME=ingress-nginx、SW_BACKEND_SERVERS=http://skywalking-oap:12800 - 修改模板中的
init_by_lua_block,从os.getenv读取服务名与地址,避免硬编码
对于快速验证,可直接使用阿里云提供的预编译镜像:docker run -d -p 80:80 -e BACKEND_URL=http://your-oap:12800 registry.cn-hangzhou.aliyuncs.com/public-community/skywalking-nginx-lua:0.2











