【剖析 | SOFARPC 框架】系列之 SOFARPC 数据透传剖析

简介: Scalable Open Financial Architecture是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。

SOFA

Scalable Open Financial Architecture

是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。

本文为《剖析 | SOFARPC 框架》第八篇,作者水寒,目前就职于网易。

《剖析 | SOFARPC 框架》系列由 SOFA 团队和源码爱好者们出品,
项目代号:,官方目录目前已经全部认领完毕,文末提供了已完成的文章目录。


image.png

前言

在《剖析 | SOFARPC 框架》系列之前的文章中,我们已经介绍了同步,异步,泛化调用等,也介绍了链路追踪的能力。

本篇,我们将介绍一下 SOFARPC 中另一种内置的数据透传的能力。依次介绍,数据透传的概念, SOFARPC 的设计原理,以及各种不同调用方式下的透传使用和详细说明,最后, 还会比较一下和 SOFATracer 的区别。欢迎大家与我们讨论交流。

数据透传介绍

首先,我们知道,在 RPC 调用中,数据的传递,是通过接口方法参数来传递的,需要接口方定义好一些参数允许传递才可以。在一些场景下,我们希望,能够更通用的传递一些参数,比如一些标识性的信息。业务方可能希望,在每一次调用请求中都能够传递一些自定义的信息到下游。甚至也希望下游能够将一些数据传递回来。

而数据透传功能,就是指数据不需要以作为方法参数的形式在调用链路中进行传递,而是直接存储到调用上下文中,之后通过 RPC 的内置对象,进行传递,调用双端可从上下文中获取数据而不需要去关注数据的传输过程。SOFARPC 提供的数据透传支持请求数据透传(客户端向服务端)和响应数据透传(服务端向客户端)

SOFARPC 设计原理

这里主要是介绍一下,实现的核心原理,更加具体的每种调用方式的透传,在后文中都会详细介绍。

image.png

  • 用户通过 SOFARPC 提供的 API 进行数据传递设置
  • SOFARPC 在调用传输前,将透传的数据进行打包获取
  • 进行正常的序列化和反序列化
  • SOFARPC 在反序列化时将用户设置的透传数据写回 Context
  • 服务端用户即可进行获取使用

不同调用方式的透传

我们知道,SOFARPC 目前支持四种调用模式,如果没有阅读过之前文章的同学,可以阅读一下 SOFARPC 同步异步实现剖析 。四种调用模式下,请求透传数据的原理都是一样的,服务端设置响应透传数据的原理也是一样的,只是客户端获取响应透传数据的方式有所不同(后三种模式只介绍客户端获取响应透传数据的原理)。

因此我们会介绍下不同调用方式的透传细节,并介绍其使用方式,方便大家理解。以下为了方便说明,我们会使用如下的接口示例

接口服务

public interface HelloService {
    String sayHello(String string);
}

服务实现

public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String string) {
        // 获取请求透传数据并打印
        System.out.println("service receive reqBag -> " + RpcInvokeContext.getContext().getRequestBaggage("req_bag"));
        // 设置响应透传数据到当前线程的上下文中
        RpcInvokeContext.getContext().putResponseBaggage("resp_bag", "s2c");
        return "hello " + string + " !";
    }
}

后续的所有调用模式都使用HelloServiceImpl这个服务实现。(示例代码在 SOFARPC 的测试 case 中都要对应的示例,大家可以对应阅读)

对用户可见的操作 API 只有一个就是 RpcInvokeContext,在 SOFABoot 和 SOFARPC 下都适用,当然如果你了解 SOFARPC 的 Filter 机制,也可以通过扩展这个来实现。

一、sync 调用下的透传
使用示例
image.png

原理剖析
image.png

请求透传数据
客户端首先在 main 线程(图中的user thread)中设置请求透传数据到其调用上下文RpcInvokeContext.requestBaggage属性中,之后在调用过程中从requestBaggage中取出请求透传数据并设置到SofaRequest.requestProps属性中。

服务端接收到请求SofaRequest对象后,在其调用链中的 ProviderBaggageFilter#invoke 方法中会先从SofaRequest.requestProps中取出请求透传数据并设置到当前服务端线程的调用上下文RpcInvokeContext.requestBaggage属性中,最后业务代码就可以从调用上下文中获取请求透传数据了。

响应透传数据
服务端设置响应透传数据到其调用上下文RpcInvokeContext.responseBaggage属性中,之后在ProviderBaggageFilter#invoke 方法中先从responseBaggage中取出响应透传数据并设置到SofaResponse.responseProps属性中。

客户端main线程被唤醒后,先从SofaResponse.responseProps中获取响应透传数据,之后将响应透传数据设置到其调用上下文RpcInvokeContext.responseBaggage中,最后业务代码就可以从调用上下文中获取响应透传数据了。

二、oneway 调用下的透传
使用示例

image.png

原理剖析

image.png

在 oneway 模式下,客户端不接受服务端响应,也不会获取响应透传数据。

三、future 调用下的透传
使用示例
image.png

原理剖析

image.png

客户端获取响应透传数据
future 模式在 SOFARPC 内部会被转化为 callback 的方式进行调用,在 callback 对象中会存储main线程的调用上下文;当客户端接收到响应时,会执行该 callback 对象的回调函数,在其回调函数中,对于响应透传数据,会做如下操作:

从SofaResponse.responseProps中获取响应透传数据

从 callback 对象中获取 main 线程的调用上下文

设置响应透传数据到 main 线程的调用上下文

将 main 线程上下文拷贝到当前的回调线程中

实际上,第三步与第四步在 SOFARPC 源码中顺序相反,本文这样解读是为了更容易理解。这样无论是 future 模式(从 main 线程的调用上下文获取响应透传数据)还是 callback 模式(从回调线程的调用上下文获取响应透传数据),都可以顺利的获取到响应透传数据。

四、callback 调用下的透传
使用示例

image.png

原理剖析

image.png

与future模式原理一样,只是最终业务代码中是从回调线程而不是main线程的调用上下文中获取响应透传数据。

与 SOFATracer 的比较

如果了解过 SOFATracer 的同学会有疑问,这个跟 Tracer 是不是有功能上的重叠呢?实际上 SOFATracer 是蚂蚁开源的一个分布式链路追踪系统,SOFARPC 目前已经和 Tracer 做了集成,默认开启。

和 Tracer 进行数据传递不同的是

  • SOFARPC 的数据透传更偏向业务使用,而且可以在全链路中进行双向传递,调用方可以传给服务方(请求透传数据),服务方也可以传递信息给调用方(响应透传数据),SOFATracer 更加偏向于中间件和业务无感知的数据的传递,并且只能进行单向传递。也就是向下传递,调用方并不能获取服务提供方的透传数据。
  • SOFARPC 的透传可以选择性地不在全链路中透传(主动清除调用上下文数据),而 Tracer 中如果传递大量信息,会在整个链路中传递。可能对下游业务会有影响。

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

目录
相关文章
|
7月前
|
Dubbo Java 应用服务中间件
从源码全面解析 dubbo 服务端服务调用的来龙去脉
从源码全面解析 dubbo 服务端服务调用的来龙去脉
|
7月前
|
缓存 Dubbo Java
Dubbo 第三节_ Dubbo的可扩展机制SPI源码解析
Dubbo会对DubboProtocol对象进⾏依赖注⼊(也就是⾃动给属性赋值,属性的类型为⼀个接⼝,记为A接⼝),这个时候,对于Dubbo来说它并不知道该给这个属性赋什么值,换句话说,Dubbo并不知道在进⾏依赖注⼊时该找⼀个什么的的扩展点对象给这个属性,这时就会预先赋值⼀个A接⼝的⾃适应扩展点实例,也就是A接⼝的⼀个代理对象。在调⽤getExtension去获取⼀个扩展点实例后,会对实例进⾏缓存,下次再获取同样名字的扩展点实例时就会从缓存中拿了。Protocol是⼀个接。但是,不是只要在⽅法上加了。
|
4月前
|
负载均衡 Dubbo 应用服务中间件
Dubbo服务调用过程原理
该文章主要介绍了Dubbo服务调用过程的原理,包括服务调用的主要阶段和服务调用的具体步骤。
Dubbo服务调用过程原理
|
负载均衡 Dubbo 应用服务中间件
不满足于RPC,详解Dubbo的服务调用链路(1)
不满足于RPC,详解Dubbo的服务调用链路
377 0
|
XML 编解码 JSON
不满足于RPC,详解Dubbo的服务调用链路(2)
不满足于RPC,详解Dubbo的服务调用链路
233 0
|
XML Java 数据格式
【剖析 | SOFARPC 框架】之SOFARPC 同步异步实现剖析
我们对 RPC 框架中的同步异步实现进行了一些详细的分析,并深入介绍了 SOFARPC 中的实现细节,感谢大家。
2354 0
|
网络协议 前端开发 Java
【剖析 | SOFARPC 框架】之SOFARPC 连接管理与心跳剖析
本文介绍连接管理的策略和SOFARPC中连接管理与心跳机制的实现,希望通过这篇文章,大家对此有一个了解,如果对其中有疑问的,也欢迎留言与我们讨论。
1832 0
|
Java
【剖析 | SOFARPC 框架】系列之 SOFARPC 同步异步实现剖析
Scalable Open Financial Architecture 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
874 0
|
Java 缓存 微服务
【剖析 | SOFARPC 框架】系列之 SOFARPC 优雅关闭剖析
Scalable Open Financial Architecture 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
870 0
|
Java 数据格式 JSON
【剖析 | SOFARPC 框架】系列之SOFARPC跨语言支持剖析
Scalable Open Financial Architecture 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
1068 0