Biz-SIP业务中台案例实战(18)——调用App延迟服务

2023-05-06 04:02:21

 

Biz-SIP金融级业务中台(http://bizsip.bizmda.com)是一套基于领域驱动设计(DDD)架构,能快速构建金融级云原生架构的服务整合中间件,整合了在金融场景里锤炼出来的最佳实践。

分布式事务是分布式系统架构设计中的一个技术难点,特别是在这几年越来越火的微服务架构中,服务拆分所带来的跨服务数据一致性问题亟待解决,而在金融系统中,这个问题更是备受关注。

在Biz-SIP金融业务中台中,是利用App延迟服务,来提供对分布式事务的支持,主要场景有:

1. 重试通知:通知对方系统,如果对方系统没有响应,会重新发起通知交易,直到对方给出明确的回复响应。

2. 向前补偿:调用第三方服务后,超时没有响应,系统会后续发起查询上笔交易状态的查询交易,如果对方系统还是没响应,会多次重试再发起交易状态查询,并根据查询交易状态来决定继续完成后续服务步骤(上笔交易终态查询结果为已成功)还是对以前服务步骤发起补偿(冲正)操作(上笔交易终态查询结果为未成功)。

3. 向后补偿:调用第三方服务后,超时没有响应,系统会立即发起针对此交易的补偿交易,如果对方系统还是没响应,会多次重试再发起补偿交易。补偿成功后,会对以前服务步骤依次发起补偿(冲正)操作;如果补偿失败,会置交易失败,由人工介入处理。

调用App延迟服务案例,是通过Biz-SIP的开放API接口,调用App服务,再由App服务发起对App延迟服务的多次重试调用:

在以上案例中,有2个App服务:

/bean/sample15:正常的App服务,被开放API接口所调用,模拟在特定场景(发起重试通知、调用第三方应用后无响应)中调用App延迟服务;/bean/sample15-delay:被调用的App延迟服务,模拟和第三方应用交互的不同场景(无响应、返回错误、返回成功)。

具体代码和配置可以查看Biz-SIP源代码中的Sample相关测试案例(

https://gitee.com/szhengye/biz-sip)

一、App层App服务的开发和配置

首先,我们需要编写一个App服务类(Sample15AppService.java):

@Slf4j @Service public class Sample15AppService implements AppBeanInterface { private BizMessageInterface bizMessageInterface = AppClientFactory.getDelayAppServiceClient( BizMessageInterface.class, "/bean/sample15-delay", 0,1000, 2000, 4000, 8000, 16000); @Override public JSONObject process(JSONObject message) throws BizException { BizMessage<JSONObject> bizMessage = this.bizMessageInterface.call(message); return bizMessage.getData(); } }

Sample15AppService类继承了AppBeanInterface接口,实现了process()方法。

Sample15AppService类中申请了调用“/bean/sample15-delay”App延迟服务的调用接口bizMessageInterface,在process()方法中,通过这个接口,来调用App延迟服务。

接着,我们还需要编写一个App服务类作为App延迟服务(Sample15DelayAppService.java):

@Slf4j @Service public class Sample15DelayAppService implements AppBeanInterface { @Override public JSONObject process(JSONObject message) throws BizException { log.info("延迟App服务调用第[{}]次: \n{}", BizUtils.getDelayRetryCount(), BizUtils.buildJsonLog(message)); int maxRetryCount = message.getInt("maxRetryCount"); String result = (String) message.get("result"); if (BizUtils.getDelayRetryCount() >= maxRetryCount) { if ("success".equalsIgnoreCase(result)) { log.info("返回成功!"); return message; } else { log.info("返回错误!"); throw new BizException(BizResultEnum.OTHER_ERROR,"Sample15DelayAppService调用错误!"); } } log.info("抛出延迟App服务重试异常,触发下一次调用..."); throw new BizException(BizResultEnum.RETRY_DELAY_APP_SERVICE); } }

Sample15AppService类同样继承了AppBeanInterface接口,实现了process()方法。

Sample15AppService类中,会根据传入报文中的“maxRetryCount”来决定调用次数,在没达到maxRetryCount约定的最大重试次数时,会直接抛出App服务重试异常(异常错误码为BizResultEnum.RETRY_DELAY_APP_SERVICE);传入报文中的“result”为达到最大重试次数后是返回成功(result为“success”)还是直接抛出异常(除App服务重试异常以外的其它BizException异常)。

然后,在app.yml中,需要配置这二个App服务:

- app-service-id: /bean/sample15 type: app-bean-service class-name: com.bizmda.bizsip.sample.app.service.Sample15AppService - app-service-id: /bean/sample15-delay type: app-bean-service class-name: com.bizmda.bizsip.sample.app.service.Sample15DelayAppService

二、启动应用进行测试

启动SampleAppApplication应用,通过OpenAPI接口进行测试。

首先,请求报文中设置最大重试次数(maxRetryCount)为4,最终返回结果(result)为“success”。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data {"maxRetryCount":4,"result":"success"} http://localhost:8888/api|jq { "code": 0, "message": "success", "extMessage": null, "appServiceId": "/bean/sample15", "traceId": "35a40e4bace44883bcb6511a3b016b82", "parentTraceId": null, "timestamp": 1648358690842, "data": { "maxRetryCount": 4, "result": "success" } }

SampleAppApplication应用中被调用的Sample15DelayAppService类打印日志:

[bizsip-integrator:192.169.1.103:8888] 13:24:50 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[1]次: { "maxRetryCount": 4, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:24:50 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:24:51 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[2]次: { "maxRetryCount": 4, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:24:51 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:24:53 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[3]次: { "maxRetryCount": 4, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:24:53 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:24:58 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[4]次: { "maxRetryCount": 4, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:24:58 INFO 70936 [7a36a3f4c22e40a49792931645570553] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] c.b.b.s.a.s.Sample15DelayAppService 返回成功!

可以看到Sample15DelayAppService类一共被调用了4次,最后返回成功,中间的时间间隔分别为1秒、2秒、5秒(时间精确度关系,略有误差)。

其次,请求报文中设置最大重试次数(maxRetryCount)为3,最终返回结果(result)为“fail”。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data {"maxRetryCount":3,"result":"fail"} http://localhost:8888/api|jq { "code": 0, "message": "success", "extMessage": null, "appServiceId": "/bean/sample15", "traceId": "a60d017e00554dd6a779a478ced2c7f5", "parentTraceId": null, "timestamp": 1648359627667, "data": { "maxRetryCount": 3, "result": "fail" } }

SampleAppApplication应用中被调用的Sample15DelayAppService类打印日志:

[bizsip-integrator:192.169.1.103:8888] 13:40:27 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-5] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[1]次: { "maxRetryCount": 3, "result": "fail" } [bizsip-integrator:192.169.1.103:8888] 13:40:27 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-5] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:40:28 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[2]次: { "maxRetryCount": 3, "result": "fail" } [bizsip-integrator:192.169.1.103:8888] 13:40:28 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:40:30 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[3]次: { "maxRetryCount": 3, "result": "fail" } [bizsip-integrator:192.169.1.103:8888] 13:40:30 INFO 70936 [2b2564ca72d74251b3e1d7bac2a99242] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 返回错误!

可以看到Sample15DelayAppService类一共被调用了3次,最后返回失败,中间的时间间隔分别为1秒、2秒。

最后,请求报文中设置最大重试次数(maxRetryCount)为8,最终返回结果(result)为“success”。

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/bean/sample15" -X POST --data {"maxRetryCount":8,"result":"success"} http://localhost:8888/api|jq { "code": 0, "message": "success", "extMessage": null, "appServiceId": "/bean/sample15", "traceId": "19e559c658954b35861a32369b08f5b1", "parentTraceId": null, "timestamp": 1648359793722, "data": { "maxRetryCount": 8, "result": "success" } }

SampleAppApplication应用中被调用的Sample15DelayAppService类打印日志:

[bizsip-integrator:192.169.1.103:8888] 13:43:13 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[1]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:13 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:14 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[2]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:14 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:16 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-5] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[3]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:16 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-5] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:20 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[4]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:20 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-4] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:28 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[5]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:28 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-3] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:44 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 延迟App服务调用第[6]次: { "maxRetryCount": 8, "result": "success" } [bizsip-integrator:192.169.1.103:8888] 13:43:44 INFO 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.s.a.s.Sample15DelayAppService 抛出延迟App服务重试异常,触发下一次调用... [bizsip-integrator:192.169.1.103:8888] 13:43:44 WARN 70936 [6040bebfe86545e5a5bdbf36e4e25376] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-2] c.b.b.a.l.DelayAppServiceQueueListener 延迟App服务重试次数超过次数[6],服务失败!

可以看到Sample15DelayAppService类一共被调用了6次,最后提示“延迟App服务重试次数超过次数[6],服务失败!”,中间的时间间隔分别为1秒、2秒、4秒、8秒、16秒。

Biz-SIP官方网站:http://bizsip.bizmda.com

Gitee:

https://gitee.com/szhengye/biz-sip


以上就是关于《Biz-SIP业务中台案例实战(18)——调用App延迟服务》的全部内容,本文网址:https://www.7ca.cn/baike/22822.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明

排行榜