概述
异步通讯一般发生在生产与消费不等的情况,这类请求可能需要同步请求转异步请求,应用需要通过MQ消息队列来进行5类情况处理:
•异步处理
•应用解耦
•流量消峰
•日志处理
•消息通讯
目前从业务应用架构模式上来说,异步处理、应用解耦、流量消峰比较常用。通常情况下,我们对同步请求转异步请求处理。
同步请求转异步请求模式:可以通过同步EDAS通讯框架,降低前端业务系统对MQ中间件的依赖,然后能更好的通过同步通讯框架来实现路由、分组、限流、熔断等处理。并且可以快速通过水平扩展模式来提高并发。而且对自发自首MQ完全由业务系统来进行控制,对于MQ的使用量上会大大减少,对MQ的隔离和扩展上大大增加。
目前业务异步通讯的问题
上述两张图,反应出目前MQ在使用场景中的弊端
1.应用A无法知道应用B是否接收到请求,也无法对请求作出预判。
2.应用A如果出现大量错误请求的时候,对MQ来说是未知的,只会无故积压,导致影响后续正确的交易。
3.应用B如果出现幂等请求情况下,应用A大量重复交易,必须通过异步请求来返回,这个时候会发现异步请求解耦被没有在正确的大量数据处理上运用。导致大量重复积压。
4.应用A和B对MQ进行强依赖,变成各个系统间的集中处理中间件,万一发生问题,影响面很大。
5.应用A和应用B在扩容上比较困难,需要考虑全局MQ的性能问题。
6.应用A和应用B在MQ层面很难实现熔断、降级、路由、负载均衡策略。
同步请求转异步请求模式
模式一
•应用A使用EDAS Request请求应用B。
o需要验证服务端逻辑,避免不必要的请求开销
•应用B验证逻辑不通过(入参验证、幂等、安全验证等),错误直接返回EDAS Response请求到应用A。
o服务端验证应该避免远程调用,因为异步请求模式下,需要达到相应速度和应答速度来提高并发,整个请求操作应该在10MS之内。
•应用B验证逻辑通过,直接落DB或Redis等,保证业务持久可靠后,直接返回EDAS Response请求到应用A
o落DB需要快速响应,可以考虑热点表,此类表因为是大量Insert操作,考虑尽量少建索引来提高并发。整个请求操作应该在 20MS之内。
•应用B自已发送MQ请求,异步解耦,自己接收自己发送的MQ请求后,处理正确的业务逻辑。
o发送MQ请求,可以考虑异步发送,提高并发,因为之前已经落DB成功,但需要考虑在接收端处理业务逻辑的时候,需要进行DB验证。
•应用B处理完成的请求结果,在通过应用A暴露的EDAS请求进行接口回调,将结果给到应用A。
•使用场景:同步请求并发量比较大。
模式二
•前面接模式一说明
•应答处理发送应答MQ进行流量消峰处理,然后接受应答,在通过应用A暴露的EDAS/Http请求进行接口回调,将结果给到应用A。
•使用场景:同步请求并发比较大,异步应答并发比较大。
模式三
•前面接模式二说明
•应用A接收到应用B的回调应答后,发送回调MQ进行流量消峰处理,在慢慢进行自行业务逻辑处理。
注意
•使用场景:同步请求并发比较大,异步应答并发比较大并发,对方应用系统异步回调请求并发大。
•其中模式一、二、三虚线中可以考虑减少对DB的依赖,如果业务系统对数据可靠性要求是有补偿机制的话,那么可以直接发MQ进行处理,更好提升异步处理性能。
异常处理
第1步EDAS通讯异常,客户端需要考虑熔断来快速返回,服务端应考虑实际并发进行限流。
第2步验证异常,服务端需要考虑交易严格幂等情况下,重复交易情况下查询重复交易请求,有终态直接返回,中间态考虑入DB后丢弃,保证前端只有一个返回。前端调用系统在接收到重复请求的同时,也进行终态判断,保证交易一致性。
第3步发MQ异常,需要有定时补偿调度线程进行交易补偿,数据终态已数据库DB为准。
第4步接收MQ异常,需要考虑MQ重试机制,重试次数不要过多,3次最多,每次间隔不宜过长,否则MQ会挤压(有些业务场景对交易时效有要求,比如1分钟内必须要得到终态等)。
接口参数处理
•应用B EDAS 服务同步请求参数定义,里面可以包含应用A需要异步返回的参数。
o接口名称:pg:XXXXX_async
o接口方法:XXXXX_async
o接口参数:应用参数+callbackParams(HashMap)
• 应用B EDAS 服务同步请求返回参数定义,包含应答状态、描述、具体返回值(Json格式)。
o 参数1:asyncStatus
o 参数2:asyncMsg
o 参数3:asyncJson(callbackParams+业务返回字段)
• 应用B 接收请求自发自收MQ定义,可以根据上层业务产品号(可以依赖配置中心维护)。
o 队列名:Q_xxx_xxx_1001(Q_应用B项目名_应用A项目名_产品号)
o 队列信息:json(应用A EDAS请求全部信息)
• 应用A EDAS 服务回调接口定义,包含应答状态、描述、具体返回值(Json格式)(接口应该相对固化,防止改动引起不兼容上线)。
o 接口方法:pg:XXXXX_asyncCallback
o 方法:XXXXX_asyncCallback
o 参数1:asyncCallbackStatus
o 参数2:asyncCallbackMsg
o 参数3:asyncCallbackJson(callbackParams+业务返回字段)
o 返回值:asyncCallbackId(请求唯一ID)
接口回调协议
• EDAS:直接使用EDAS RPC调用(推荐)。
• Http:服务方需要通过SLB提供负载均衡地址(负载均衡必须是Http负载均衡,包含健康页面,不要Session粘滞,推荐使用PoolingHttpClientConnectionManager并且实现Http1.1 Keepalive模式)。
优势和应用规范
- 应用A非常明确的知道应用B给出的正确应答(可以及时进行业务逻辑处理,如:参数验证错误、幂等重复、系统异常等情况)。
- 应用B可以清晰给出同步请求强类型接口,实现接口的单一职责,明确接口参数规范。
- 应用B作为服务端,可以使用EDAS接口带来的路由、熔断、限流、负载均衡策略等功能。
- 应用B发布过程中,可以使用EDAS接口带来的灰度、分区、水平扩展等功能。
- 应用B自发自收MQ,可以轻松隔离,明确数据所属边界。
处理一(落DB后发送MQ异步处理)
应用规范
• 可靠性强(DB数据作为业务唯一数据存储点,DB的数据可靠性比MQ强)。
• 一致性强(DB支持ACID)。
• 对数据可控性强(业务可以对DB中数据进行查询、过滤、统计,可以方便选择数据进行处理或放弃)。
• 并发要求不是很高(因为依赖DB,DB的插入和查询有一定开销)
• 异步落DB数据需要清理(插入DB的数据,可以定期归档或消费后直接删除)。
适用场景
• 需要同步转异步解耦。
• 业务请求必须以服务端应答作为依赖处理。
• 对业务数据需要强一致性、可靠性,并且对业务数据有复杂逻辑处理和过滤。
处理二(直接发送MQ后异步处理)
应用规范
• 可靠性弱(MQ作为数据存储,其可靠性不如DB)。
• 一致性弱(MQ不能保证重复消息)。
• 对数据可控性弱(MQ中的消息积压后,无法进行复杂的查询和过滤)。
• 高并发强(MQ的数据吞吐能力比DB强)
• 数据自动清理(MQ数据消费后自动清理和定期归档)。
适用场景
• 需要同步转异步解耦。
• 业务请求必须以服务端应答作为依赖处理。
• 高并发场景,依赖MQ作为高吞吐处理,消息本身业务属性不强,可以无序消费。
• 不包含同一类系统内部通讯:数据边界和业务边界同属于一个系统
总结
同转异框架本身需要进行异步消息推送SDK转发能力,来实现多个EDAS服务的注册对应完成异步转同步的能力,在通过同步通讯框架EDAS的能力,最终将上下层耦合解除,MQ的能力上有所减弱,但MQ变成应用的私有属性,能更好的扩展。