Bolt 协议调用方式

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

调用方式

SOFARPC 在 Bolt 协议下提供了多种调用方式满足不同的场景。

同步

在同步的调用方式下,客户端发起调用后会等待服务端返回结果再进行后续的操作。这是 SOFARPC 的默认调用方式,无需进行任何设置即可。

异步

异步调用的方式下,客户端发起调用后不会等到服务端的结果,继续执行后面的业务逻辑。服务端返回的结果会被 SOFARPC 缓存,当客户端需要结果的时候,再主动调用 API 获取。如果需要将一个服务设置为异步的调用方式,在对应的使用方式下设置 type 属性即可:

XML 方式

在 XML 方式下,设置 <sofa:global-attrs> 标签的 type 属性为 future 即可:

<sofa:reference interface="com.example.demo.SampleService" id="sampleService">
    <sofa:binding.bolt>
        <sofa:global-attrs type="future"/>
    </sofa:binding.bolt>
</sofa:reference>

Annotation 方式

在 Annotation 方式下,设置 @SofaReferenceBindinginvokeType 属性为 future 即可:

@SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt", invokeType = "future"))
private SampleService sampleService;

Spring 环境下 API 方式

在 Spring 环境下使用 API,设置 BoltBindingParamtype 属性即可:

BoltBindingParam boltBindingParam = new BoltBindingParam();
boltBindingParam.setType("future");

在非 Spring 环境下 API 方式

在非 Spring 环境下使用 SOFARPC 裸 API,设置 ConsumerConfiginvokeType 属性即可:

ConsumerConfig<SampleService> consumerConfig = new ConsumerConfig<SampleService>()
    .setInterfaceId(SampleService.class.getName())
    .setRegistry(registryConfig)
    .setProtocol("bolt")
    .setInvokeType("future");

获取调用结果

使用异步调用的方式,目前提供了两种方式来获取异步调用的结果:

直接获取结果

用户可以通过以下的方式来直接获取异步调用的结果:

String result = (String)SofaResponseFuture.getResponse(0, true);

其中第一个参数是获取结果的超时时间,第二个参数表示是否清除线程上下文中的结果。

获取 JDK 原生 Future

用户可以通过以下的方式来获取 JDK 的原生的 Future 对象,再可以从任意地方去调用这个 Future 对象来获取结果:

Future future = SofaResponseFuture.getFuture(true);

其中的第一个参数表示是否清除线程上下文中的结果。

回调

SOFARPC Bolt 协议的回调方式可以让 SOFARPC 在发起调用后不等待结果,在客户端收到服务端返回的结果后,自动回调用户实现的一个回调接口。

使用 SOFARPC Bolt 协议的回调方式,首先需要实现一个回调接口,并且在对应的配置中设置回调接口,再将调用方式设置为 callback

实现回调接口

SOFARPC 提供了一个回调的接口 com.alipay.sofa.rpc.core.invoke.SofaResponseCallback,用户使用 SOFARPC Bolt 协议的回调方式,首先需要实现这个接口,该接口提供了三个方法:

  • onAppResponse:当客户端接收到服务端的正常返回的时候,SOFARPC 会回调这个方法。
  • onAppException:当客户端接收到服务端的异常响应的时候,SOFARPC 会回调这个方法。
  • onSofaException:当 SOFARPC 本身出现一些错误,比如路由错误的时候,SOFARPC 会回调这个方法。

设置回调接口

实现回调接口之后,用户需要将实现类设置到对应的服务引用配置中,并且将调用方式设置为 callback。

SOFARPC 为设置回调接口提供了两种方式,分别为 Callback Class 和 Callback Ref。Callback Class 的方式直接设置回调的类名,SOFARPC 会通过调用回调类的默认构造函数的方式生成回调类的实例。Callback Ref 的方式则为用户直接提供回调类的实例。

XML 方式

如果通过 XML 的方式引用服务,将 <sofa:global-attrs> 标签的 type 属性设置为 callback,并且设置 callback-ref 或者 callback-class 属性即可:

<bean id="sampleCallback" class="com.example.demo.SampleCallback"/>
<sofa:reference interface="com.example.demo.SampleService" id="sampleService">
    <sofa:binding.bolt>
        <sofa:global-attrs type="callback" callback-ref="sampleCallback"/>
    </sofa:binding.bolt>
</sofa:reference>

在 XML 的方式下,callback-ref 的值需要是回调类的 Bean 名称。

Annotation 方式

如果通过 Annotation 的方式引用服务,设置 @SofaReferenceBinding 注解的 invokeType 属性为 callback,并且设置 callbackClass 或者 callbackRef 属性即可:

@SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt",
            invokeType = "callback",
            callbackRef = "sampleCallback"))
private SampleService sampleService;

在 Annotation 的方式下,callbackRef 属性的值需要是回调类的 Bean 名称。

Spring 环境 API 方式

如果在 Spring 或者 Spring Boot 的环境下使用 API 的方式,设置 BoltBindingParamtype 属性为 callback,并且设置 callbackClass 或者 callbackRef 属性即可:

BoltBindingParam boltBindingParam = new BoltBindingParam();
boltBindingParam.setType("callback");
boltBindingParam.setCallbackClass("com.example.demo.SampleCallback");
非 Spring 环境下 API 方式

如果在非 Spring 环境下使用 SOFARPC 的裸 API,调用 setInvokeType 将类型设置成 callback,并且调用 setOnReturn 设置回调类即可:

ConsumerConfig<SampleService> consumerConfig = new ConsumerConfig<SampleService>()
    .setInterfaceId(SampleService.class.getName())
    .setRegistry(registryConfig)
    .setProtocol("bolt")
    .setInvokeType("callback")
    .setOnReturn(new SampleCallback());
在调用级别设置回调接口

除了在服务级别设置回调接口之外,还可以在调用级别设置回调接口,方式如下:

RpcInvokeContext.getContext().setResponseCallback(new SampleCallback());

单向

当客户端发送请求后不关心服务端返回的结果时,可以使用单向的调用方式,这种方式会在发起调用后立即返回 null,并且忽略服务端的返回结果。

使用单向的方式只需要将调用方式设置为 oneway 即可,设置方式和将调用方式设置为 future 或者 callback 一样,这里不再重复讲述,可以参考上面的文档中提供的设置方式。

需要特别注意的是,由于单向的调用方式会立即返回,所以所有的超时设置在单向的情况下都是无效的。