hyperf链路追踪ui空白主因是tracer未启动或数据未上报:driver必须显式设为'zipkin'且层级正确,endpoint_url需指向skywalking zipkin receiver,timeout须合理,app信息要准确,tracemiddleware与aspect缺一不可。

Hyperf 链路追踪 UI 显示空白,90% 是因为 tracer 没真正启动或数据根本没发出去——不是“装了就完事”,而是配置错一个字段、少注册一个中间件、driver 写错层级,链路就彻底断在起点。
opentracing.php 里 driver 必须显式设为 'zipkin'
Hyperf 的 hyperf/tracer 组件默认不激活任何驱动,'default' => env('TRACER_DRIVER', 'zipkin') 这行必须存在,且环境变量 TRACER_DRIVER 要明确设为 zipkin。如果留空、写成 jaeger 或拼错(比如 zipkinv2),整个 'zipkin' 配置块会被忽略,连初始化都不触发。
-
'zipkin'键必须直接挂在'tracer'数组下一级,不能嵌在'jaeger'或其他块里 - 别把
'driver' => ZipkinTracerFactory::class写进'jaeger'配置里——Jaeger driver 根本不认这个字段 - 同时配了 zipkin 和 jaeger?只启用其中一个,避免驱动冲突
endpoint_url 和 timeout 是唯二必须校验的上报参数
endpoint_url 必须指向 SkyWalking OAP 的 Zipkin receiver 接口,比如 http://skywalking-oap:9411/api/v2/spans,不是 Jaeger 的 UDP 地址,也不是 Collector 的 gRPC 接口。HTTP 上报依赖连接池和超时控制,timeout 设太小(如 0.1)会导致 span 丢弃且无任何错误提示。
- 本地测试可用
http://localhost:9411/api/v2/spans,但容器内要确保能解析localhost到宿主机(推荐用host.docker.internal或显式 IP) -
ZIPKIN_ENDPOINT环境变量值必须带完整路径/api/v2/spans,少写会返回 404,tracer 却不报错 - 别用
https协议,除非 OAP 明确启用了 TLS,否则请求静默失败
app 名称、IP、端口填错会导致服务显示为“未知”
'app' 数组里的 'name'、'ipv4'、'port' 会生成 Zipkin 的 Endpoint,直接影响 SkyWalking UI 中的服务名、IP 标签和端口归属。填错会导致多个实例被聚合成一个“未知服务”或分散在不同节点下。
-
'name'建议用env('APP_NAME'),且各服务间不能重复(如都写hyperf-service) -
'ipv4'在 Kubernetes 中应设为env('POD_IP'),不是127.0.0.1;本地开发可固定为127.0.0.1 -
'port'要与 Hyperf 实际监听端口一致(如9501),否则拓扑图里服务端口显示错误
TraceMiddleware 和 Aspect 缺一不可
仅配好 opentracing.php 不会自动埋点。HTTP 入口靠 TraceMiddleware 拦截并创建根 Span;Guzzle、Redis、Db 等调用靠对应 Aspect 类拦截并续传上下文。任一缺失,链路就会断在某一层。
-
config/autoload/middlewares.php中必须注册\Hyperf\Tracer\Middleware\TraceMiddleware::class - 检查
config/autoload/opentracing.php中'enable'配置是否开启对应组件,比如'guzzle'=>true、'db'=>true - 若用的是 Hyperf 3.0+,旧版
jaeger-client-php已不可靠,必须改用opentelemetry/sdk+ OTLP,否则协程上下文会错乱,Span 泄漏
最常被忽略的是:tracer 初始化时机和传播器使用方式——OpenTelemetry 必须在主协程启动前完成全局 TracerProvider 初始化,且 HTTP 中间件里必须用 CompositeTextMapPropagator 解析 traceparent,手动拼接 header 值会导致 trace_id 不匹配,UI 显示 “broken link”。











