求教,有状态的分布式系统应该如何设计

273 天前
 mawen0726

应对业务扩张,将服务拆分并支持横向扩展,现在拆了共 a,b,c 三个服务出来,然后这三个服务要设计成可以随时横向扩展。其中有如下调用链路

然后 c 是主要处理业务的服务,会上分布式锁,加上处理时间长,会后台执行并执行完通知上游来做其他业务操作,业务操作之后才能解锁。

因为一个业务只能在一个 c 中执行,所以解锁要找到对应的 c 。比如 a 执行业务分配到节点 1 的 c,后续交互都要找节点 1 的 cb是批量执行业务,这一批都要到同一个c中执行完。

目前设计方案是将 c的 IP 和业务 id 写到 redis ,然后通过 redis 确定业务在哪个 c 节点上面跑着。然后要在业务处理过程中,查看状态都通过 redis 查对应 ip 再去调用服务。

比如批量任务中,a 要确定哪个 b 节点承接了这个业务,b 节点确定哪个 c 节点正在处理这批次业务。

感觉这种设计不是很好,想请教下还有没有更优雅的做法

可能描述的有点复杂,大概意思是

怎么记录在多个节点时,知道这个任务在哪个节点上,并且应用之间相对不耦合

3274 次点击
所在节点    程序员
46 条回复
mawen0726
260 天前
@Plutooo
其实正是这个线程的问题,才让我发帖问的,原本我以为 redisson 只是简单的 key 相同解锁...
后面稍微深入了一下,其实就是分了两个类型
1. 线程 id 必须一样
2. lockasync ,指定一个 id ,使用相同 id 上锁解锁即可(可以联想场景 reactor java ,每个场景都可能是不同的线程执行的)

但是抛开这个不谈,原本要维护下游 ip 还是很垃圾的设计...
mawen0726
260 天前
@aarontian
当时认为 c 去锁定资源,就认为 c 去上锁了,其实还说漏了一些,c 和资源会建立 ws 连接,所以当时就更认为要在 c 上锁...
希望可以看看我新的回复,看看这种设计怎么样,算是第一次做种比较复杂的设计
huzhizhao
260 天前
@mawen0726 #39 没有绝对好的,适合就好。得看你从什么角度考量。
但从复杂度上来说,整个系统的结构是复杂了的。
mark2025
259 天前
@mawen0726 感觉 主题 2 、3 、4 都可以合并,用执行状态键值表示 完成、终端、取消等状态
mark2025
259 天前
@mawen0726 你这个场景使用任务队列来做应该还算简单了:
1. 发布任务消息到消息队列(带执行)
2. 收到任务消息,上锁,发布任务状态消息(已上锁)
3. 收到已上锁的行任务消息,开始执行任务。根据任务执行结果(成功、失败),发布任务状态消息(执行状态,可以包含任务结果数据)
4. 收到包含执行状态的任务消息,解锁

抽象为 4 个步骤,使用任务状态值在消息队列中来流转,可以忽略 a 、b 、c 具体服务。
mark2025
259 天前
a -> b -> c
a -> c
两种调用链路可以设计为两个队列 topic ,以上面 4 步为基础对 步骤 3 进行扩展就行了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1097140

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX