以前分析了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