|
112 | 112 |
|
113 | 113 | #### SpanSet 连接 |
114 | 114 |
|
115 | | -SpanSet 之间两两互相连接,并标记他们之间的 Parent 关系。总共有如下五种连接的场景,依次从上到下按优先级来挂。其中,1/2/3/4 包含如下限制条件: |
| 115 | +SpanSet 之间两两互相连接,并标记他们之间的 Parent 关系。连接分为两个阶段: |
| 116 | + |
| 117 | +- **准确连接阶段**(场景 1-6):基于强关联证据(span_id、x_request_id、tcp_seq、grpc stream_id、trace_id+协议特征)建立连接,依次按优先级执行。 |
| 118 | +- **弱关联阶段**(场景 7):仅在准确连接阶段完成并清空匹配状态后执行,通过配置项 `span_set_connection_strategies` 控制是否开启,基于 trace_id 做推断性连接。 |
| 119 | + |
| 120 | +其中,场景 1-5 包含如下通用约束条件: |
116 | 121 |
|
117 | 122 | 约束条件: |
118 | 123 | - 避免「同组 SpanSet 」首尾的 Span 满足上述 1.2. 条件发生首尾互连,限制满足条件的两个 Span 不能是同一个 SpanSet [代码位置](https://github.com/deepflowio/deepflow-app/blob/v6.6.3/app/app/application/l7_flow_tracing.py#L2319) |
@@ -156,11 +161,32 @@ SpanSet 之间两两互相连接,并标记他们之间的 Parent 关系。总 |
156 | 161 | - 如果 x_request_id_0 等于 x_request_id_1,无额外要求,意味着中间有个网关做 x_request_id 注入,直接匹配挂接 |
157 | 162 | - 一个 NetworkSpanSet 的结尾 Span span_id 等于另一个 NetworkSpanSet 的开头 Span 的 span_id [代码位置](https://github.com/deepflowio/deepflow-app/blob/v6.6.3/app/app/application/l7_flow_tracing.py#L2480) |
158 | 163 | - 同时要求前者所有 Span 的最大 response_duration 比后所有 Span 的最小值要大,与 x_request_id_0/1 对应相等的场景处理办法完全相同 |
| 164 | + - 对 gRPC/HTTP2 协议,一个 NetworkSpanSet 的结尾 Span 的 `request_id`(来源于 gRPC stream_id)等于另一个 NetworkSpanSet 的开头 Span 的 `request_id`,且后者时延 ≤ 前者时延(包括双方时延均为 0 的情况) |
| 165 | + - 仅支持 gRPC/HTTP2,因为其他协议(如 MySQL StatementID)的 request_id 可能短期内被重用,容易产生误连接 |
159 | 166 |
|
160 | 167 | <div align=center> |
161 | 168 | <img src="./design/3.5.svg" width=50%> |
162 | 169 | </div> |
163 | 170 |
|
| 171 | +6. 针对 WebSphereMQ 异步消息场景的特殊连接:client 侧叶子 NetworkSpanSet → server 侧根 NetworkSpanSet |
| 172 | +- 仅适用于协议为 WebSphereMQ 且携带 `is_async` 标识的 Span |
| 173 | +- 连接条件:双方 trace_id 有交集,且 client 侧叶子 Span 无子节点、server 侧根 Span 无父节点 |
| 174 | +- 场景含义:`user → MQ | MQ → user`,两组逻辑上有关系但数据层面仅有 trace_id 可能关联的异步流 |
| 175 | +- 时序约束:对同一个 agent_id,要求 client 侧 Span 开始时间早于 server 侧 Span(而非 time_range_cover,因为是异步) |
| 176 | +- 如有多个候选 parent,取开始时间最大(最接近)的 parent |
| 177 | + |
| 178 | +7. 弱关联:client 侧叶子 NetworkSpanSet → server 侧根 NetworkSpanSet(通过 trace_id 推断) |
| 179 | +- **仅在配置项 `span_set_connection_strategies` 包含 `net_span_c_to_s_via_trace_id` 时生效** |
| 180 | +- 此场景在场景 1-6 全部执行并清空匹配状态后,作为独立的弱关联阶段单独运行,不干扰准确连接 |
| 181 | +- 连接条件: |
| 182 | + - client 侧叶子 Span(`tap_side` 以 `c` 开头)无子节点(`children_count == 0`) |
| 183 | + - server 侧根 Span(`tap_side` 以 `s` 开头)无父节点(`parent_id < 0`),且 `is_net_root` 为真 |
| 184 | + - 双方 trace_id 有交集 |
| 185 | + - 双方 tcp_seq 不同(相同 tcp_seq 意味着已在同一 NetworkSpanSet 内,无需再连) |
| 186 | + - 叶子 Span 的 `response_duration` ≥ 根 Span 的 `response_duration` |
| 187 | +- 如有多个候选 parent,取 `response_duration` 最小(最接近)的 parent |
| 188 | +- 此连接为推断性质,准确性低于场景 1-6,适用于 tcp_seq 不同但 trace_id 相同的跨 SpanSet 场景(如经过网关后 tcp 连接发生变化) |
| 189 | + |
164 | 190 | ### 裁剪 |
165 | 191 |
|
166 | 192 | 裁剪是排序的后续清理步骤 ,避免因为错误的关联而产生了错误的追踪结果。 |
|
0 commit comments