怎么保证web分布式系统中接口调用的顺序性
本篇内容介绍了"怎么保证web分布式系统中接口调用的顺序性"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
问题引入
一般来说,我们多个接口的调用是不用保证顺序的,但是有的时候,有的业务场景可能确实是需要严格的顺序来保证系统的准确性。
举个例子,分布式架构中的服务A调用服务B,发了两个请求,一个插入操作一个删除操作,本来是先插入再删除。但是很可能俩请求过去了,集群部署的情况下落在了不同机器上,可能插入请求因为某些原因执行慢了一些,导致删除请求先执行了,此时因为没数据所以没有啥效果没有啥影响;接着这个时候插入执行完了,好,把数据插入进去了,这不就完全错了嘛。
本来应该是插入 -> 删除,最终这条数据应该没了,结果现在是删除 -> 插入,导致最后数据还存在,然后你死都想不明白是怎么回事。你只能通过不同机器上的日志去看,费半天劲去查,最后比对俩操作的执行时间,可能最后也能查出来问题所在。
这,就是分布式系统中一个很常见的问题,那我们该如何保证接口的调用顺序呢?
解决方案分析
1、尽量避免引入顺序性
首先,一般来说,我个人给你的建议是,你们从业务逻辑上最好设计的这个系统不需要这种顺序性的保证,因为一旦引入顺序性保障,我们就需要引入一些的别的、复杂的技术(如分布式锁)来保证,这样会导致系统的复杂度上升,而且会导致系统性能下降,吞吐量降低,热点数据压力过大等问题。
2、一致性hash+内存队列
其次,如果不得不保证顺序性的话,下面给个我们用过的方案吧。
简单来说,首先你得用一致性hash负载均衡策略,将比如同一个订单id对应的请求都给分发到同一个机器上去。接着就是在那个机器上,因为可能还是多线程并发执行的,你就得将这个订单id对应的请求扔进一个内存队列里去,强制排队,这样来确保他们的顺序性。
如下图所示:
3、分布式锁
复杂点的,使用基于zookeeper的分布式锁来实现接口调用的强顺序性。
首先服务A发送的三个有序请求请求1、2、3,依次发送到消息对列,然后服务B的多个实例从消息对列消费。假如分别是三个实例拿到了1/2/3三个请求,那么当请求执行时需要小从zookeeper获取锁,才能执行。所以此时我们的服务A还要指明这三个请求的执行顺序,即seq=1/2/3,服务B才能知道执行顺序。
这时候三个请求都来获取锁,假如请求3先获取到锁,然后看Redis这个list是不是有比自己小的序号,有则释放锁。然后如果请求1拿到了锁,也去Redis判断是不是有比自己小的序号,一看没有,就执行请求1,然后从Redis的list里删掉这个序号。。。依次这样来获取锁->判断->删除redis里的序号。。。来保证接口的顺序性。
如下图所示:
"怎么保证web分布式系统中接口调用的顺序性"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!