在云环境中编写Messenger聊天机器人时,我面临一些并发问题。
具体来说,我希望确保来自同一对话的传入消息得到一个接一个的处理
作为一个限制,我在云环境中与工作人员一起处理消息(即工作人员池大小可变,工作人员实例可能很短,可能会崩溃)。此外,低延迟也很重要。
所以抽象一点,我的要求是:
- 我有一连串的传入消息
- 每个消息都有一个"主题密钥"(会话id)
- 这组主题并不提前知道,而且几乎是无限的
- 我想确保同一主题的消息被连续处理
- 关于一群可能昙花一现的工人
- 如果可能的话,我希望得到可靠性保证,例如确保每条消息只处理一次
我的问题是:
- 这个并发场景是否有名称
- 是否有技术(消息代理、协调服务等)可以开箱即用地实现这一点
- 如果没有,我可以使用什么算法在较低级别的并发工具之上实现这一点?(分布式锁、参与者、队列等)
我不知道这个场景有一个被广泛接受的名称,但解决这类问题的一个常见策略是路由消息,使所有具有相同主题键的消息最终到达同一目的地。有几项技术可以为您做到这一点:
- 使用Apache ActiveMQ、HornetQ或Apache ActiveMQ Artemis,您可以将主题密钥用作JMSXGroupId,以确保具有相同主题密钥的所有消息都由同一使用者按顺序处理,并进行故障切换
- 使用ApacheKafka,您可以使用主题密钥作为分区密钥,这也将确保具有相同主题密钥的所有消息都由同一消费者按顺序处理
一些消息代理供应商将此要求称为消息分组、粘滞会话或粘性消息负载平衡。
对于交付/订购保证较弱的消息系统(如亚马逊SQS),另一种常见策略是在消息中简单地包含一个序列号,并由目的地根据需要重新排序和请求重新交付丢失的消息。
我认为可以通过使用队列和集合来解决这个问题。我能想到的是发送队列中的每个消息对象,并将其作为先进先出进行处理。但在将其添加到队列中时,在集合中添加主题名称,并将其取出进行处理时,从集合中删除主题名称。所以现在,若集合中有任何主题,那个么就不要在队列中添加另一个相同主题的消息对象。我希望这对你有帮助。最好的:)