Bolt 协议的调用方式

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 属性为 future

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

  • 在非 Spring 环境下 API 方式

    在非 Spring 环境下使用 SOFARPC 的裸 API,设置 ConsumerConfiginvokeType 属性为 future

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

获取调用结果

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

  • 直接获取结果

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

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

    其中,0 表示获取结果的超时时间,您可以根据需要修改;true 表示清除线程上下文中的结果。若您不希望清除结果,可以修改为 false

  • 获取 JDK 原生 Future

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

    Future future =SofaResponseFuture.getFuture(true);

    true 表示清除线程上下文中的结果。若您不希望清除,可以修改为 false

回调

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 属性。以 callback-ref为例,代码如下:

    <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 属性。以 callback-ref为例,代码如下:

    @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 属性即可。以 callbackClass为例,代码如下:

    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(newSampleCallback());

在调用级别设置回调接口

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

RpcInvokeContext.getContext().setResponseCallback(newSampleCallback());

单向

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

使用单向的方式只需将调用方式设置为 oneway 即可,设置方式和将调用方式设置为 future 或者 callback 一样,您可以参考上面的文档中提供的设置方式。需要特别注意的是,由于单向的调用方式会立即返回,所有的超时设置在单向的情况下都是无效的。