Biz-SIP金融级业务中台(http://bizsip.bizmda.com)是一套基于领域驱动设计(DDD)架构,能快速构建金融级云原生架构的服务整合中间件,整合了在金融场景里锤炼出来的最佳实践。
Biz-SIP业务中台支持多种连接方式的通讯适配器(Connector),包括TCP、RabbitMQ、HTTP、调用Spring服务等通讯适配方式。
RabbitMQ Connector作为Sink服务可以调用的通讯适配器,基于RabbitMQ中间件RPC调用方式,特别适合在Sink端实现基于RabbitMQ的同异步转换。
本节案例中是在Sink服务中,通过RabbitMQ Connector,和RabbitMQ侦听类(RabbitmqConnectorSinkQueueListener类)进行通讯交互:
其中,App层是通过Sink透传App服务,直接让调用方通过OpenAPI接口调用Sink服务(rabbitmq-connector-sink),Sink服务调用simple-json类型的格式转换器,把平台内部标准格式(JSONObject对象,内部即JSON报文)简单打包成JSON报文,传给RabbitMQ Connector,通过RabbitMQ中间件RPC调用模式,和开发的RabbitMQ侦听类(RabbitmqConnectorSinkQueueListener类)进行通讯交互,返回后再把JSON报文解包成平台内部标准格式返回。
具体代码和配置可以查看Biz-SIP源代码中的Sample相关测试案例(https://gitee.com/szhengye/biz-sip)
一、Sink层Sink服务的开发和配置
首先,在Biz-SIP配置目录的sink.yml中,配置对应的Sink服务:
- id: rabbitmq-connector-sink
type: rest
url: http://bizsip-sample-sink/rabbitmq-connector-sink
converter:
type: simple-json
connector:
type: rabbitmq
exchange: exchange.direct.bizsip.sink
routing-key: key.bizsip.rabbitmq-connector-sink
可以看到rabbitmq-connector-sink这个Sink服务,connector类型为rabbitmq,并设置了相关参数(exchange为发送交换器,routing-key为发送路由主键)。格式转换器converter,设置为“type: simple-json”,采用最简单解包打包机制(直接打包成JSON,并对JSON直接解包成平台内部标准报文)。
这个Sink服务没有设置processor属性,即为缺省default类型,采用默认的缺省Sink服务流程来处理的,处理步骤依次为:
- 调用格式转换器converter对传入报文进行打包;
- 对上步打包后的报文作为调用请求报文,调用通讯适配器connector进行处理,并收到并返回响应报文;
- 调用格式转换器converter对响应报文进行解包,并返回解包后的报文。
最后,还需要在SampleSinkApplication的应用配置文件application-local.yml中,在bizsip.sink-id配置项中,增加rabbitmq-connector-sink以便启动Sink服务:
bizsip:
config-path: /var/bizsip/config
sink-id: hello-sink,echo-sink,simple-xml-sink,velocity-json-sink,velocity-xml-sink,fixed-length-sink,velocity-split-sink,iso-8583-sink,sample17-sink,netty-sink,rabbitmq-connector-sink
二、第三方外部应用的开发
第三方外部应用为RabbitMQ侦听类,代码如下:
@Slf4j
@Service
public class RabbitmqConnectorSinkQueueListener {
@Autowired
private RabbitTemplate rabbitTemplate;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue.bizsip.rabbitmq-connector-sink", durable = "true", autoDelete = "false"),
exchange = @Exchange(value = "exchange.direct.bizsip.sink", type = ExchangeTypes.DIRECT, durable = "true", autoDelete = "false"),
key = "key.bizsip.rabbitmq-connector-sink"))
public void onMessage(Message inMessage) {
byte[] bytes = inMessage.getBody();
log.debug("收到报文:\n{}",BizUtils.buildHexLog(bytes));
Message outMessage = MessageBuilder.withBody(bytes)
.setCorrelationId(inMessage.getMessageProperties().getCorrelationId())
.build();
rabbitTemplate.send("",
inMessage.getMessageProperties().getReplyTo(),
outMessage);
return;
}
}
可以看到,RabbitmqConnectorSinkQueueListener类在onMessage()方法上加了@RabbitListener注解,定义了队列"queue.bizsip.rabbitmq-connector-sink",绑定的交换器和路由主键和sink.yml中rabbitmq-connector-sink定义的exchange和routing-key是一致的。
在onMessage()方法中,回送的outMessage的CorrelationId和回送的队列名,都是取自inMessage中的CorrelationId和ReplayTo队列,以保证能把消息正确返回给RPC调用请求方。
三、App层App服务的开发和配置
对于Sink透传App服务,只需要在app.yml中配置即可:
- app-service-id: /sink/rabbitmq-connector-sink
type: sink-service
sink-id: rabbitmq-connector-sink
可以看到在app.yml中,配置了App服务“/sink/rabbitmq-connector-sink”,类型为Sink透传App服务(sink-service),透传调用的Sink服务为“rabbitmq-connector-sink”。
四、启动应用进行测试
启动SampleSinkApplication、SampleAppApplication应用,通过OpenAPI接口进行测试:
curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/rabbitmq-connector-sink" -X POST --data '{"accountNo":"003"}'
{
"code": 0,
"message": "success",
"extMessage": null,
"appServiceId": "/sink/rabbitmq-connector-sink",
"traceId": "ccce2248eff0461f96ecc569caa4bbc9",
"parentTraceId": null,
"timestamp": 1647871612226,
"data": {
"accountNo": "003"
}
}
第三方应用模拟类(RabbitmqConnectorSinkQueueListener类)打印日志:
收到报文:
====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII ====== +
0000: 7B 22 61 63 63 6F 75 6E 74 4E 6F 22 3A 22 30 30 33 22 7D | {"accountNo":"003"}. |
Biz-SIP网站:http://bizsip.bizmda.com
Gitee代码库:https://gitee.com/szhengye/biz-sip