【发布时间】:2015-11-02 00:00:18
【问题描述】:
在我们公司,我们有一个分布在几个实例中的服务器。服务器处理用户请求。来自不同用户的请求可以并行处理。来自同一用户的请求应按顺序执行。但是由于平衡,它们可以到达不同的实例。目前我们使用基于 Redis 的分布式锁,但这很容易出错,并且需要围绕并发进行比业务逻辑更多的工作。
我想要的是这样的(更像是一个概念):
- 每个用户都有不同的队列
- 队列以用户 ID 命名
- 每个请求都由请求 ID 标识
-
假设来自同一用户的两个请求同时到达两个不同的实例:
- 每个实例都将其请求 ID 放入此用户队列。
- 此外,它们都将请求 ID 存储在本地。
- 然后某个代理从“some_user_queue”顶部获取请求 ID 并将其移动到“some_user_queue_processing”中
- 两个实例都侦听“some_user_queue_processing”。他们偷看它,看看这是否是他们在本地存储的请求 ID。如果是,则进行处理。如果没有,则忽略并等待。
- 工作完成后,服务器会从“some_user_queue_processing”中删除此 ID。
- 然后再次执行第 3 步。
所有这一切同时发生在许多(数千个)不同用户(及其队列)中。
现在,我知道这听起来很像演员,但是:
- 我们需要的解决方案需要尽可能小的更改才能从锁定中快速过渡。 Akka 将迫使我们从头开始重写几乎所有内容。
- 我们需要生产就绪的解决方案。 Quasar 听起来不错,但尚未准备好生产(更准确地说,是他们的 Galaxy 集群)。
- 我工作的上层非常保守,他们根本不想要我们需要支持的另一个依赖项。但是我们已经在使用 Redis(用于分布式锁),所以我想也许它也可以帮助解决这个问题。
谢谢
【问题讨论】:
-
也许你可以评估一下 Hazelcas 对分布式锁的支持,见hazelcast.org/#lock。
-
假设有粘性会话,在 Java 8 中编写 dispatch queue 很简单。
-
你能告诉我我的答案是不是你真正需要的吗?
标签: java concurrency redis distributed task-queue