Jaeger和Zipkin在PHP中需显式配置且协议不兼容;Hyperf中tracer驱动必须设为'jaeger',仅认agent_host、agent_port、service_name三字段,UDP上报无重试易丢数据。

Jaeger 和 Zipkin 在 PHP 中不能“自动接入”,必须显式配置驱动、地址、服务名,且两者协议和传输方式差异大——填错一个字段,数据就彻底静默丢失,UI 里什么也看不到。
Hyperf 里 tracer 配置 driver 必须写 'jaeger',不是 'zipkin' 或留空
Hyperf 的 tracer 组件默认不启用任何驱动,driver 字段为空或设为 'zipkin' 时,Jaeger 配置块会被完全忽略。即使你写了 'jaeger' => [...],只要顶层 'driver' => 'zipkin',Jaeger 就不会初始化。
-
config/autoload/tracer.php中必须明确设置:'driver' => 'jaeger' -
'jaeger'子数组只认三个键:'agent_host'、'agent_port'、'service_name',其余字段(如'endpoint'、'sampler')全被丢弃 - 开发时用
'agent_host' => '127.0.0.1',别写'localhost'—— Docker 容器内它解析成自己,连不到宿主机的 Jaeger Agent -
'agent_port'固定是6831(UDP Compact Thrift),不是14268(HTTP)或14250(gRPC)
Guzzle HTTP 请求怎么透传 traceparent?靠 Middleware 注入 header
Guzzle 本身不带追踪能力,必须用 MiddleWare::tap() 在请求发出前生成 Span 并注入上下文。Zipkin 和 Jaeger 都支持 W3C Trace Context 标准,所以统一用 traceparent header 即可,不用区分后端是哪个。
- Span 必须在
mapRequest阶段创建,并调用$span->activate()激活作用域 - 用
$request->withHeader('traceparent', $span->getContext()->getTraceParent())透传 - 响应/错误回调中要显式
$span->finish(),否则 Span 不上报 - 别依赖
$tracer->flush()—— Guzzle 是长连接复用场景,flush()可能触发过早清空缓冲区
Jaeger UDP 上报无重试、无日志,丢包就丢数据
Hyperf 和原生 jaeger-client-php 默认都走 UDP 向 agent:6831 发送 span,这是轻量设计,但也是最大隐患:网络抖动、agent 崩溃、单个 span 超 65KB,都会导致数据静默消失,Tracer 类既不抛异常也不打 warning 日志。
- 本地验证可用:
docker run -d --name jaeger -p 6831:6831/udp -p 16686:16686 jaegertracing/all-in-one - 生产环境建议加一层 UDP 包监控(如
netstat -su查看 UDP receive errors) - 若必须可靠上报,得换用 Zipkin driver + HTTP endpoint(
http://zipkin:9411/api/v2/spans),它有连接池、重试和 JSON 错误反馈 - Jaeger 的
agent_host不能指向 Collector 的 HTTP 地址 —— 那是 Zipkin 的玩法,Jaeger agent 和 collector 是分离角色
真正容易被忽略的是:所有 tracer 初始化都发生在 DI 容器构建阶段,一旦服务启动,service_name 和 agent_host 就固定了;改配置必须重启进程,环境变量热加载对 tracer 无效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











