zipkin源碼 3.zipkin client brave-okhttpclient

以前分析了sr,ss,接下來分析cr,cs 下面以okhttp client爲例:ide

@Bean
public OkHttpClient okHttpClient(Brave brave) {
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(
                    new BraveOkHttpRequestResponseInterceptor(
                            brave.clientRequestInterceptor(),
                            brave.clientResponseInterceptor(),
                            new DefaultSpanNameProvider()))
            .build();
    return client;
}

上面代碼建立了OkHttpClient,而且織入了攔截器,在真正請求執行前、後觸發。ui

下面看BraveOkHttpRequestResponseInterceptor的intercept方法this

@Override
  public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    Request.Builder builder = request.newBuilder();
    OkHttpRequest okHttpRequest = new OkHttpRequest(builder, request);
    //前置處理
    clientRequestInterceptor.handle(new HttpClientRequestAdapter(okHttpRequest, spanNameProvider));
    if(request.url()!=null&&request.url().query()!=null){
      clientTracer.submitBinaryAnnotation("params",request.url().query());
    }
    //真正的請求處理
    Response response = chain.proceed(builder.build());
    //後置處理
    clientResponseInterceptor.handle(new HttpClientResponseAdapter(new OkHttpResponse(response)));
    return response;
  }

首先看前置處理:url

public class ClientRequestInterceptor {

    private final ClientTracer clientTracer;

    public ClientRequestInterceptor(ClientTracer clientTracer) {
        this.clientTracer = checkNotNull(clientTracer, "Null clientTracer");
    }

    /**
     * Handles outgoing request.
     *
     * @param adapter The adapter deals with implementation specific details.
     */
    public void handle(ClientRequestAdapter adapter) {
        //經過clientTracer建立SpanId,對應有ServerTracer
        SpanId spanId = clientTracer.startNewSpan(adapter.getSpanName());
        if (spanId == null) {
            // We will not trace this request.
            adapter.addSpanIdToRequest(null);
        } else {
            //將span信息放入header中,便於傳遞
            adapter.addSpanIdToRequest(spanId);
            //jiang將uri信息存入binaryAnnotation
            for (KeyValueAnnotation annotation : adapter.requestAnnotations()) {
                clientTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue());
            }
            //添加cs annotation到span
            recordClientSentAnnotations(adapter.serverAddress());
        }
    }

    private void recordClientSentAnnotations(Endpoint serverAddress) {
        if (serverAddress == null) {
            clientTracer.setClientSent();
        } else {
            clientTracer.setClientSent(serverAddress);
        }
    }
}

下面看後置處理:spa

public class ClientResponseInterceptor {

    private final ClientTracer clientTracer;

    public ClientResponseInterceptor(ClientTracer clientTracer) {
        this.clientTracer = checkNotNull(clientTracer, "Null clientTracer");
    }

    /**
     * Handle a client response.
     *
     * @param adapter Adapter that hides implementation details.
     */
    public void handle(ClientResponseAdapter adapter) {
        try {
            //將響應碼添加到BinaryAnnotation
            for (KeyValueAnnotation annotation : adapter.responseAnnotations()) {
                clientTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue());
            }
        }
        finally
        {    
            //設置cr狀態,而且提交span
            clientTracer.setClientReceived();
        }
    }
}

其實還有一種trace,那就是lc,即localTracer,它的使用方法以下:code

//生成新的span
 localTracer.startNewSpan("codec", "encode");
   try {
    //業務處理
   } finally {
     tracer.finishSpan();
   }

localTracer能夠嵌入業務代碼,根據本身的業務需求添加,跟蹤代碼塊好比file io操做,業務指標好比下單次數等。server

總結

1.zipkin brave基於ServerRequestInterceptor、ServerResponseInterceptor、ClientRequestInterceptor、ClientResponseInterceptor四種攔截器來處理的。ip

相關文章
相關標籤/搜索