微服务优化之异步调用

前一节《微服务优化之并行》,主要从并行的角度来提高微服务的响应时间,本节讲一下微服务优化之异步调用。异步的前提是对依赖的RPC接口调用,不需要关心其执行结果,对数据没有强一致性要求,只要能够达到最终一致性就好。

该种情况下,实现方式一般有两种:

第一种,对于最终一致性要求很低的情况,比如当用户投资抢标的情况下,只要用户的请求到达服务端,并且校验通过允许抢购,就可以记录用户抢购申请,冻结资金,并且立即返回成功,缩短接口响应时间,从而挺高系统吞吐率。然后在系统后台,启动一个定时任务,定时扫描申请表中的记录,调用内部标的认购接口,调用外部资金划拨接口,生成自己划拨流水,并且更新抢购申请单状态,完成完整的标的认购,达到最终数据的一致性。

第二种,对于数据实时性要求稍微高一点的,需要借助于消息队列,在分布式服务系统中一般会采用分布式消息中间件来辅助完成微服务的异步化。常用的分布式消息中间件有Kafka、RabbitMQ、RocketMQ、Apache Artemis等等,各个中间的优缺点和用法这里不多做介绍。

基于消息的异步该怎么做呢?当接口接收到客户端请求后,向消息中间件发送消息,并立即返回成功,靠消息中间件来保证数据的最终一致性。然而这样做还是不够的,还需要考虑以下三种情况:

1,如果消息发送失败了怎么办?

2,如果消息发送成功了,消息中间件丢消息,或者消费方业务失败怎么办?

3,如果消息发送成功了,但是返回信息时网络中断导致消息生产方以为消息发送失败怎么办?

那么针对以上情况,需要做一下工作:

1,消息生产方需要一个本地事件表,记录事件流水,事件表至少包含以下状态:消息发送成功,消息发送失败,消息发送状态未知,业务未执行,业务执行成功,业务执行失败

2,消息生产方需要一个回调接口

3,消息消费方需要一个本地事件表,记录消费方事件流水,事件表至少包含以下状态:业务重试次数,业务执行成功,业务执行失败,业务回滚

基于以上说明,那么总的执行流程就很清晰了,当客户端调用我们的RPC时,首先记录本地事件表,然后发送消息,并根据消息发送结果更新事件表状态。消息消费方接受消息后,首先记录本地事件表,然后自行业务逻辑,再根据业务逻辑执行结果更新本地事件表状态,最后在调用回调接口来更新消息生产方的事件表状态。最后再通过Job拉取消息生产方的事件表,和消息消费方的事件表对比进行额外的数据补偿达到最终的一致性。这样通过消息中间件达到绝大多数请求的准实时性,同时提高对外接口的响应效率。

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐