链路数据透传

链路数据透传功能支持应用向调用上下文中存放数据,使得整个链路上的应用都可以操作该数据。

您可以分别向链路的 request 和 response 中放入数据进行透传,并可获取到链路中相应的数据。使用方式如下:

RpcInvokeContext.getContext().putRequestBaggage("key_request","value_request");
RpcInvokeContext.getContext().putResponseBaggage("key_response","value_response");

String requestValue=RpcInvokeContext.getContext().getRequestBaggage("key_request");
String responseValue=RpcInvokeContext.getContext().getResponseBaggage("key_response");

使用示例

例如数据从 A 到 B,再到 C 的场景中,将 A 设置的请求隐式传参数据传递给 B 和 C。在返回的时候,将 C 和 B 的响应隐式传参数据传递给 A。

A 请求方设置:

// 调用前设置请求透传的值。
RpcInvokeContext context =RpcInvokeContext.getContext();
context.putRequestBaggage("reqBaggageB","a2bbb");
// 调用。
String result = service.hello();
// 拿到结果透传的值。
context.getResponseBaggage("respBaggageB");

B 业务代码:

public String hello(){
    // 拿到请求透传的值。
    RpcInvokeContext context =RpcInvokeContext.getContext();
    String reqBaggage = context.getRequestBaggage("reqBaggageB");
    doSomthing();
    // 结果透传一个值。
    context.putResponseBaggage("respBaggageB","b2aaa");
    return result;
}

如果中途自己启动了子线程,则需要设置子线程的上下文:

CountDownLatch latch =new CountDownLatch(1);
finalRpcInvokeContext parentContext =RpcInvokeContext.peekContext();
Thread thread =new Thread(new Runnable(){
    public void run(){
          try{
                RpcInvokeContext.setContext(parentContext);
                // 调一个远程服务。
                xxxService.sayHello();
                latch.countDown();
          }finally{
               RpcInvokeContext.removeContext();
          }
    }
},"new-thread");
thread.start();

// 此时拿不到返回值透传的数据的。
latch.await();//等待
// 此时返回结束,能拿到返回透传的值。

和 SOFATracer 的比较

SOFATracer 是蚂蚁开源的一个分布式链路追踪系统,RPC 目前已经集成 Tracer,默认开启。

RPC 和 Tracer 进行数据传递不同点如下:

  • RPC 的数据透传更偏向业务使用,而且可以在全链路中进行双向传递。调用方可以传给服务方,服务方也可以传递信息给调用方。SOFATracer 更加偏向于中间件和业务无感知的数据的传递,只能进行单向传递。

  • RPC 的透传可以选择性地不在全链路中透传,而 Tracer 中如果传递大量信息,会在整个链路中传递,可能对下游业务会有影响。

所以整体来看,两者各有利弊,在有一些和业务相关的透传数据的情况下,可以选择 RPC 的透传。