Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >如何保证分布式系统中接口调用的顺序性?

如何保证分布式系统中接口调用的顺序性?

作者头像
编程大道
发布于 2020-01-16 03:18:30
发布于 2020-01-16 03:18:30
2.3K0
举报
文章被收录于专栏:编程大道编程大道

能坚持别人不能坚持的,才能拥有别人不能拥有的。 关注编程大道公众号,让我们一同坚持心中所想,一起成长!!

如何保证分布式系统中接口调用的顺序性?

分布式是当下比较流行的一个话题,很多大型的互联网公司都是分布式系统,将一个大而全的系统拆分成多个小而精的一个个的功能单一、职责集中的子系统,系统之间通过约定好的协议、规则进行调用,降低系统之间的耦合度,避免牵一发而动全身。

虽然分布式系统的架构有很多的好处,但不得不说它也存在很多需要特别注意的问题。我们今天要讲的分布式系统中接口的调用顺序,就是其中一个很常见的问题。

问题引入

一般来说,我们多个接口的调用是不用保证顺序的,但是有的时候,有的业务场景可能确实是需要严格的顺序来保证系统的准确性。

举个例子,分布式架构中的服务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里的序号。。。来保证接口的顺序性。

如下图所示:

结语

你看看,上面为了保证接口调用的顺序性是不是又引入了很多复杂的技术,所以这样后续就会引发很多问题。比如说要是某个订单对应的请求特别多,造成某台机器成热点怎么办?这样系统的增加了系统的复杂度,同时系统的性能、吞吐量也会明显降低,引入zookeeper分布式锁这种很重的机制,势必会带来这些副作用。而解决这些问题又要开启后续一连串的复杂技术方案。。。

曾经这类问题弄的我们头疼不已,所以,还是建议什么呢?建议尽量避免引入顺序性,在系统设计时就避免这个问题,或者最好是像刚才那样一个订单的插入和删除操作,能不能合并成一个操作,就是一个删除,或者是什么,避免这种问题的产生。

欢迎一起学习交流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BiggerBoy 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
分布式系统互斥性与幂等性问题的分析与解决
前言 随着互联网信息技术的飞速发展,数据量不断增大,业务逻辑也日趋复杂,对系统的高并发访问、海量数据处理的场景也越来越多。如何用较低成本实现系统的高可用、易伸缩、可扩展等目标就显得越发重要。为了解决这一系列问题,系统架构也在不断演进。传统的集中式系统已经逐渐无法满足要求,分布式系统被使用在更多的场景中。 分布式系统由独立的服务器通过网络松散耦合组成。在这个系统中每个服务器都是一台独立的主机,服务器之间通过内部网络连接。分布式系统有以下几个特点: 可扩展性:可通过横向水平扩展提高系统的性能和吞吐量。 高可靠性
美团技术团队
2018/03/12
1.5K0
分布式系统互斥性与幂等性问题的分析与解决
实现分布式锁
在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。那具体什么是分布式锁,分布式锁应用在哪些业务场景、如何来实现分布式锁呢。
HLee
2021/04/16
3960
实现分布式锁
zookeeper分布式锁
在分布式系统中访问共享资源就需要一种互斥机制,来防止彼此之间的互相干扰,以保证一致性,就需要用到分布式锁。
JavaEdge
2018/08/02
1.8K0
zookeeper分布式锁
关于分布式锁的面试题都在这里了
最简单的理由就是作为一个社招程序员,面试的时候一定被面啦,你看怎么多公众号都翻来覆去的发分布式锁的主题,可见它很重要啦,在高考里这就是送分题,不要怪可惜的。
王炸
2020/04/26
3.2K0
分布式
在单机场景下,可以使用语言的内置锁来实现进程同步。但是在分布式场景下,需要同步的进程可能位于不同的节点上,那么就需要使用分布式锁。
全栈程序员站长
2021/04/07
4180
分布式锁实现
我们知道在同一个JVM中,可以通过Volatile、Synchronized、ReentrantLock 三个关键字来实现线程的安全。那么在分布式系统中这些是无法保证的,所以要通过分布式锁来实现。
春哥大魔王
2019/10/09
6200
分布式服务接口请求顺序性保证
服务A调用服务B,先插入再删除。俩请求过去了,落在不同机器上,可能插入请求因为某些原因执行慢一些,导致删除请求先执行了,此时因为没数据所以啥效果也没有;结果这个时候插入请求过来了,好,数据插入进去。
JavaEdge
2021/12/07
4471
基于 Redis 的分布式锁实现
很久之前有讲过并发编程中的锁「并发编程的锁机制:synchronized和lock」。在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记。
CG国斌
2020/05/19
5080
分布式服务接口请求的顺序性如何保证?
分布式系统接口的调用顺序一般来说是不用保证顺序的。但是有的时候可能确实是需要严格的顺序保证。
JavaEdge
2022/11/30
3320
万字总结 分布式系统的38个知识点
天天说分布式分布式,那么我们是否知道什么是分布式,分布式会遇到什么问题,有哪些理论支撑,有哪些经典的应对方案,业界是如何设计并保证分布式系统的高可用呢?
一灰灰blog
2022/08/23
6700
基于redis的分布式锁实现
关于分布式锁 很久之前有讲过并发编程中的锁并发编程的锁机制:synchronized和lock。在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记。 分布式环境
aoho求索
2018/04/03
1.1K0
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
前面介绍了 Zookeeper 集群 ZAB 协议、配置中心、注册中心、数据与存储、会话与事务管理等相关的知识点,今天我将详细的为大家介绍 zookeeper 分布式锁相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
民工哥
2023/09/09
1.6K0
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。
奥耶可乐冰
2024/01/11
9800
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
【JavaP6大纲】Dubbo篇:分布式服务接口请求的顺序性如何保证?
服务 A 调用服务 B,先插入再删除。好,结果俩请求过去了,落在不同机器上,可能插入请求因为某些原因执行慢了一些,导致删除请求先执行了,此时因为没数据所以啥效果也没有;结果这个时候插入请求过来了,好,数据插入进去了,那就尴尬了。本来应该是 “先插入 -> 再删除”,这条数据应该没了,结果现在 “先删除 -> 再插入”,数据还存在。
Java廖志伟
2021/04/12
3590
大厂都聊分布式系统,面试不知道分布式锁如何聊下去
公众号[JavaQ]原创,专注分享Java基础原理分析、实战技术、微服务架构、分布式系统构建,诚邀点赞关注!
JavaQ
2020/04/26
7230
分布式锁简单入门以及三种实现方式介绍
很多小伙伴在学习Java的时候,总是感觉Java多线程在实际的业务中很少使用,以至于不会花太多的时间去学习,技术债不断累积!等到了一定程度的时候对于与Java多线程相关的东西就很难理解,今天需要探讨的东西也是一样的和Java多线程相关的!
Java后端技术
2018/08/09
7570
分布式锁简单入门以及三种实现方式介绍
什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
博主负责的项目报了一个问题,用户操作回退失效。我们的设计里,操作回退是回到操作前的状态。经过查看日志发现,用户之前的操作做了两次,也就是说提交操作的接口被调用了两次,导致之用户上一次的状态和这一次的状态是一样的,所以操作回退是没有问题的,问题出在了操作的接口被调用了两次。
三分恶
2020/12/01
1.5K0
什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
Java面试——架构设计与分布式
LRU(Least Recently Used:最近最少使用):简单的说,就是保证基本的 Cache容量,如果超过容量则必须丢掉最不常用的缓存数据,再添加最新的缓存。每次读取缓存都会改变缓存的使用时间,将缓存的存在时间重新刷新。其实,就是清理缓冲的一种策略。 我们可以通过双向链表的数据结构实现 LRU Cache,链表头(head)保存最新获取和存储的数据值,链表尾(tail)既为最不常使用的值,当需要清理时,清理链表的 tail 即可,并将前一个元素设置为tail。结构图如下:
Java架构师必看
2021/04/25
6890
Java面试——架构设计与分布式
一文搞懂分布式锁的原理与实现
对于锁,大家应该都不陌生,手机上可以加锁,想用时候解锁,不用的时候上锁,那自行车、房门同样可以加把锁,道理属于类似的情况。
架构精进之路
2021/04/21
7.7K0
一文搞懂分布式锁的原理与实现
搞懂分布式技术16:浅谈分布式锁的几种方案
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/12/06
3230
推荐阅读
相关推荐
分布式系统互斥性与幂等性问题的分析与解决
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文