全部产品
云市场

配置 BOLT 服务

更新时间:2020-02-18 16:40:41

BOLT 服务的名称来自于 RPC 使用的底层通信框架 BOLT。相对于传统的 WebService,BOLT 支持更加复杂的对象,序列化后的对象更小,且提供了更为丰富的调用方式(sync、oneway、callback、future 等),支持更广泛的应用场景。

在 SOFA 中,BOLT 服务提供方使用的端口是 12200,详见 配置说明

发布及引用 BOLT 服务

SOFA 中的 RPC 是通过 Binding 模型来定义不同的通信协议的,每接入一种新的协议,就会增加一种 Binding 模型。要在 SOFA 中添加 RPC 的 BOLT 协议的实现,就需要在 Binding 模型中增加一个 <sofa:binding.bolt/>

  • 要发布一个 BOLT 的服务,请在 <sofa:service> 中添加 <sofa:binding.bolt/>,示例如下:
    1. <!-- 发布 BOLT 服务 -->
    2. <sofa:service interface="com.alipay.test.SampleService"
    3. ref="sampleService" unique-id="service1">
    4. <sofa:binding.bolt/>
    5. </sofa:service>
  • 要引用一个 BOLT 的服务,请在 <sofa:reference> 中添加 <sofa:binding.bolt/>,示例如下:
    1. <!-- 引用 BOLT 服务 -->
    2. <sofa:reference interface="com.alipay.test.SampleService" id="sampleService">
    3. <sofa:binding.bolt/>
    4. </sofa:reference>

BOLT 服务提供方配置

BOLT 的底层服务提供方是一个 Java NIO Server (Non-blocking I/O Server)。SOFA 框架提供几个选项来调整 BOLT Server 的一些属性,详见 配置说明

BOLT 服务消费方配置

BOLT 引用调用方式

BOLT 提供多种调用方式,以满足各种业务场景的需求。目前,BOLT 提供的调用方式有以下几种:

调用方式 类型 说明
sync 同步 BOLT 默认的调用方式
oneway 异步 消费方发送请求后,直接返回,忽略提供方的处理结果。
callback 异步 消费方提供一个回调接口,当提供方返回后,SOFA 框架会执行回调接口。
future 异步 消费方发起调用后,马上返回,当需要结果时,消费方需要主动去获取数据。
sync 调用

BOLT 默认的调用方式。BOLT 支持在服务提供方配置超时时间,XML 配置如下:

  1. <!-- 服务方超时设置 -->
  2. <sofa:service interface="com.alipay.test.SampleService2" ref="sampleService2">
  3. <sofa:binding.bolt>
  4. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  5. <sofa:method name="service" timeout="5000" />
  6. </sofa:binding.bolt>
  7. </sofa:service>

说明: 如果在消费方配置了超时时间,那么将以消费方的超时时间为准,提供方的超时时间将被覆盖;如果消费方没有配置,则以提供方的超时时间为准。超时时间优先级:reference method > reference global-attrs > service method > service global-attrs。

消费方的超时时间配置和提供方类似,XML 配置如下:

  1. <!-- 消费方超时配置 -->
  2. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleServiceSync">
  3. <sofa:binding.bolt>
  4. <!-- 超时全局配置 -->
  5. <sofa:global-attrs timeout="8000" test-url="127.0.0.1:12200" />
  6. <!-- 如果配置了 method ,优先使用 method 配置 -->
  7. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  8. <sofa:method name="service" type="sync" timeout="10000" />
  9. </sofa:binding.bolt>
  10. </sofa:reference>

如果没有配置 type,则默认 type 为 sync。如果有多个方法需要配置超时时间,并且超时时间都相同,也可以设置全局的超时时间。

  1. <!-- 消费方批量配置超时时间 -->
  2. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleServiceSync">
  3. <sofa:binding.bolt>
  4. <sofa:global-attrs timeout="5000" test-url="127.0.0.1:12200" />
  5. </sofa:binding.bolt>
  6. </sofa:reference>
oneway 调用

如果是 oneway 调用方式,消费方不关心结果,发起调用后直接返回,框架会忽略提供方的处理结果。在 BOLT 中,在 XML 中针对 method 的配置如下:

  1. <!-- 配置 oneway -->
  2. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleService2">
  3. <sofa:binding.bolt>
  4. <sofa:global-attrs test-url="127.0.0.1:12200" />
  5. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  6. <sofa:method name="service" type="oneway"/>
  7. </sofa:binding.bolt>
  8. </sofa:reference>

说明:由于消费方是直接返回,不关心处理结果,所以在 oneway 方式下配置超时属性是无效的。

  1. <!-- 超时设置无效 -->
  2. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleService">
  3. <sofa:binding.bolt>
  4. <sofa:global-attrs test-url="127.0.0.1:12200" />
  5. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  6. <sofa:method name="service" type="oneway" timeout="1000" />
  7. </sofa:binding.bolt>
  8. </sofa:reference>
callback 调用

callback 是一种异步回调的方式,消费方需要提供回调接口,在调用结束后,回调接口会被框架调用。XML 配置如下:

  1. <!-- callback 调用配置 -->
  2. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleService">
  3. <sofa:binding.bolt>
  4. <!-- 此处方法名 testCallback 为示例,需要替换成实际方法名 -->
  5. <sofa:method name="testCallback" type="callback" callback-class="com.alipay.test.binding.tr.MyCallBackHandler" />
  6. </sofa:binding.bolt>
  7. </sofa:reference>

上面的 callback 接口是通过配置 class 的方式来实现的,SOFA 也提供了通过引用一个 Bean 的方式来实现 callback。

  1. <!-- 使用 Bean 来实现 callback 接口 -->
  2. <bean id="myCallBackHandlerBean" class="com.alipay.test.binding.tr.MyCallBackHandler" />
  3. <sofa:reference interface="com.alipay.test.SampleService2" id="sampleService">
  4. <sofa:binding.bolt>
  5. <!-- 此处方法名 testCallback 为示例,需要替换成实际方法名 -->
  6. <sofa:method name="testCallback" type="callback" callback-ref="myCallBackHandlerBean" />
  7. </sofa:binding.bolt>
  8. </sofa:reference>

需要注意,callback 调用方式的 callback 接口必须实现 com.alipay.sofa.rpc.api.callback.SofaResponseCallback。这个接口包含三个方法,说明如下:

  1. public interface SofaResponseCallback {
  2. /**
  3. * 当服务提供方业务层正常返回结果,sofa-remoting 层将回调该方法。
  4. * @param appResponse response object
  5. * @param methodName 调用服务对应的方法名
  6. * @param request callback 对应的 request
  7. `*/
  8. public void onAppResponse(Object appResponse, String methodName, RequestBase request);
  9. /**
  10. * 当服务提供方业务层抛出异常,sofa-remoting 层将回调该方法。
  11. * @param t 服务方业务层抛出的异常
  12. * @param methodName 调用服务对应的方法名
  13. * @param request callback 对应的 request
  14. `*/
  15. public void onAppException(Throwable t, String methodName, RequestBase request);
  16. /**
  17. * 当 sofa-remoting 层出现异常时,回调该方法。
  18. * @param sofaException sofa-remoting 层异常
  19. * @param methodName 调用服务对应的方法名
  20. * @param request callback 对应的 request
  21. `*/
  22. public void onSofaException(SofaRpcException sofaException, String methodName,
  23. RequestBase request);
  24. }
future 调用

future 也是一种异步的调用方式。消费方发起调用后,马上返回,当需要结果时,消费方需要主动去获取数据。使用 future 的方式调用,配置和前面类似,只需要在 method 层面设置 type 为 future 即可。

  1. <!-- Future 调用配置 -->
  2. <sofa:reference interface="com.alipay.test.SampleService" id="sampleServiceFuture">
  3. <sofa:binding.bolt>
  4. <sofa:global-attrs test-url="127.0.0.1:12200" />
  5. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  6. <sofa:method name="service" type="future"/>
  7. </sofa:binding.bolt>
  8. </sofa:reference>

使用 future 调用,返回的结果保存在一个 ThreadLocal 线程变量里面,可以通过如下方式获取这个线程变量的值。

  1. // Future 获取调用结果
  2. public void testFuture() throws SofaException, InterruptedException {
  3. sampleServiceFuture.service();
  4. Object result = SofaResponseFuture.getResponse(1000, true);
  5. Assert.assertEquals("Hello, world!", result);
  6. }

要拿到 future 调用后的结果,只需要调用 SofaResponseFuturegetResponse 方法即可。getResponse 方法的两个参数说明如下:

  • 第一个参数是超时时间,含义是调用线程等待的最长时间,负数表示无等待时间限制,零表示立即返回,单位是毫秒。
  • 第二个参数代表是否清除 ThreadLocal 变量的值,如果设为 true,则返回 response 之前,先清除 ThreadLocal 的值,避免内存泄漏。

BOLT 引用详细配置

除了各种调用方式之外,BOLT 还在消费方提供了各种配置选项,这些选项不太常用,列举如下:

配置项 类型 说明 默认值 取值范围
connect.timeout INTEGER 消费方连接超时时间 1000 (ms) 正整数,以毫秒为单位(ms)。
connect.num INTEGER 消费方连接数 -1 -1 代表不设置(默认为每个目标地址建立一个连接)。
idle.timeout INTEGER 消费方最大空闲时间 -1 -1 表示使用底层默认值(底层默认值为 0,表示永远不会有读 idle)。
该配置也是心跳的时间间隔,当请求 idle 时间超过配置时间后,发送心跳到服务方。
idle.timeout.read INTEGER 消费方最大读空闲时间 -1 -1 表示使用底层默认值(底层默认值为 30)。
如果 idle.timeout > 0,在 idle.timeout + idle.timeout.read 时间内,如果没有请求发生,那么该连接将会自动断开。
address-wait-time INTEGER reference 生成时,等待服务注册中心将地址推送到消费方的时间。 0 (ms) 最大值为 30000 ms,超过这个值的配置将调整为 30000 ms。

BOLT 服务完整配置

BOLT 配置标签主要有两种:global-attrsmethod。如果 global-attrsmethod 同时进行了配置,那么以 method 中的配置为准。可配置的参数如下:

  • type:调用方式,有 sync、oneway、callback、future,默认为 sync。
  • timeout:超时时间,默认为 3000 ms。
  • callback-class:调用方式为 callback 时的回调对象类。
  • callback-ref:调用方式为 callback 时的回调 Spring Bean 引用。

BOLT 服务发布完整配置

  1. <sofa:service interface="com.alipay.test.SampleService" ref="sampleService" unique-id="service1">
  2. <sofa:binding.bolt>
  3. <sofa:global-attrs timeout="5000" />
  4. <!-- 此处方法名 service 为示例,需要替换成实际方法名 -->
  5. <sofa:method name="service" timeout="3000"/>
  6. </sofa:binding.bolt>
  7. </sofa:service>

BOLT 服务引用完整配置

  1. <sofa:reference id="sampleService" interface="com.alipay.test.SampleService" unique-id="service1">
  2. <sofa:binding.bolt>
  3. <sofa:global-attrs timeout="5000" test-url="localhost:12200" address-wait-time="1000"
  4. connect.timeout="1000" connect.num="-1" idle.timeout="-1" idle.timeout.read="-1"/>
  5. <!-- method 配置的属性优先级高于 global-attrs 中的配置 -->
  6. <!-- 此处方法名 futureMethod 和 callbackMethod 为示例,需要替换成实际方法名 -->
  7. <sofa:method name="futureMethod" type="future" timeout="5000" />
  8. <sofa:method name="callbackMethod" type="callback" timeout="3000"
  9. callback-class="com.alipay.test.TestCallback" />
  10. </sofa:binding.bolt>
  11. </sofa:reference>