链路数据透传

优质
小牛编辑
138浏览
2023-12-01

链路数据透传

链路数据透传功能支持应用向调用上下文中存放数据,达到整个链路上的应用都可以操作该数据。 使用方式如下,可分别向链路的 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);
final RpcInvokeContext 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 做了集成,默认开启. 和 Tracer 进行数据传递不同的是

  1. RPC的数据透传更偏向业务使用,而且可以在全链路中进行双向传递,调用方可以传给服务方,服务方也可以传递信息给调用方,SOFATracer 更加偏向于中间件和业务无感知的数据的传递,只能进行单向传递.
  2. RPC的透传可以选择性地不在全链路中透传,而Tracer 中如果传递大量信息,会在整个链路中传递.可能对下游业务会有影响.

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