分布式跟踪系统Zipkin详解(6)

回到ServerRequestInterceptor#handle()方法中final TraceData traceData = adapter.getTraceData()

@Override public TraceData getTraceData() { final String sampled = serverRequest.getHttpHeaderValue(BraveHttpHeaders.Sampled.getName()); if (sampled != null) { if (sampled.equals("0") || sampled.toLowerCase().equals("false")) { return TraceData.builder().sample(false).build(); } else { final String parentSpanId = serverRequest.getHttpHeaderValue(BraveHttpHeaders.ParentSpanId.getName()); final String traceId = serverRequest.getHttpHeaderValue(BraveHttpHeaders.TraceId.getName()); final String spanId = serverRequest.getHttpHeaderValue(BraveHttpHeaders.SpanId.getName()); if (traceId != null && spanId != null) { SpanId span = getSpanId(traceId, spanId, parentSpanId); return TraceData.builder().sample(true).spanId(span).build(); } } } return TraceData.builder().build(); }

其中SpanId span = getSpanId(traceId, spanId, parentSpanId) 将构造一个SpanId对象

private SpanId getSpanId(String traceId, String spanId, String parentSpanId) { return SpanId.builder() .traceId(convertToLong(traceId)) .spanId(convertToLong(spanId)) .parentId(parentSpanId == null ? null : convertToLong(parentSpanId)).build(); }

将traceId,spanId,parentId关联起来,其中设置parentId方法为

public Builder parentId(@Nullable Long parentId) { if (parentId == null) { this.flags |= FLAG_IS_ROOT; } else { this.flags &= ~FLAG_IS_ROOT; } this.parentId = parentId; return this; }

如果parentId为空为根节点,则执行this.flags |= FLAG_IS_ROOT ,因此后续在判断节点是否为根节点时,只需要执行(flags & FLAG_IS_ROOT) == FLAG_IS_ROOT即可.

构造完SpanId后看

serverTracer.setStateCurrentTrace(spanId.traceId, spanId.spanId, spanId.nullableParentId(), adapter.getSpanName());

设置当前Span

public void setStateCurrentTrace(long traceId, long spanId, @Nullable Long parentSpanId, @Nullable String name) { checkNotBlank(name, "Null or blank span name"); spanAndEndpoint().state().setCurrentServerSpan( ServerSpan.create(traceId, spanId, parentSpanId, name)); }

ServerSpan.create创建Span信息

static ServerSpan create(long traceId, long spanId, @Nullable Long parentSpanId, String name) { Span span = new Span(); span.setTrace_id(traceId); span.setId(spanId); if (parentSpanId != null) { span.setParent_id(parentSpanId); } span.setName(name); return create(span, true); }

构造了一个包含Span信息的AutoValue_ServerSpan对象

通过setCurrentServerSpan设置到当前线程上

继续看serverTracer.setServerReceived()方法

public void setServerReceived() { submitStartAnnotation(zipkinCoreConstants.SERVER_RECV); }

为当前请求设置了server received event

void submitStartAnnotation(String annotationName) { Span span = spanAndEndpoint().span(); if (span != null) { Annotation annotation = Annotation.create( currentTimeMicroseconds(), annotationName, spanAndEndpoint().endpoint() ); synchronized (span) { span.setTimestamp(annotation.timestamp); span.addToAnnotations(annotation); } } }

在这里为Span信息设置了Annotation信息,后续的

for(KeyValueAnnotation annotation : adapter.requestAnnotations()) { serverTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue()); }

设置了BinaryAnnotation信息,adapter.requestAnnotations()在构造HttpServerRequestAdapter时已完成

@Override public Collection<KeyValueAnnotation> requestAnnotations() { KeyValueAnnotation uriAnnotation = KeyValueAnnotation.create( TraceKeys.HTTP_URL, serverRequest.getUri().toString()); return Collections.singleton(uriAnnotation); }

以上将Span信息(包括sr)存储在当前线程中,接下来继续看BraveServletFilter#doFilter方法的finally部分

responseInterceptor.handle(new HttpServerResponseAdapter(new HttpResponse() { @Override //获取http状态码 public int getHttpStatusCode() { return statusExposingServletResponse.getStatus(); } }));

handle方法

public void handle(ServerResponseAdapter adapter) { // We can submit this in any case. When server state is not set or // we should not trace this request nothing will happen. LOGGER.fine("Sending server send."); try { for(KeyValueAnnotation annotation : adapter.responseAnnotations()) { serverTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue()); } serverTracer.setServerSend(); } finally { serverTracer.clearCurrentSpan(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f78ef258305c19bcf8576bcaef6b84ab.html