我正在处理一个系统,我必须处理多条消息,但要保留这些消息的部分顺序。我有RabbitMQ队列,有两种类型的消息:项目创建和项目更新。
考虑我们有6条消息的队列:
CREATE1 CREATE2 UPDATE1 UPDATE2 UPDATE1 UPDATE1
如果我逐个处理它们,那么它完全没问题,但它很慢,因为我有很多消息
如果我将它们读入某个缓冲区,那么我可以并行处理它们,但我可以处理UPDATE1
第一个尚未创建的项目。更糟糕的是,最后一次更新可以在前一次更新之前处理,从而删除最新的项目状态
我可以在消息中创建一些额外的字段,或者将其放入队列中,并添加一些额外的标题,例如MESSAGE_ID:10
以确保一个项目的所有邮件具有相同的MESSAGE_ID
。问题是我不知道如何处理它。
如何在不破坏消息之间的因果关系的情况下一次从队列中读取多个项目?
我为此任务想象的伪代码可能是:
const prefetchItemsCount = 20
let buffer = new Message[prefetchItemsCount]
let set = new Set()
foreach item in queue
if !set.Contains(item.MessageId)
set.Add(item.MessageId)
buffer.Add(item)
if set.Count == buffer.Count
break
return buffer
因此,在我们的示例中,它将返回以下项目序列:
CREATE1 CREATE2
UPDATE1 UPDATE2
UPDATE1
UPDATE1
这几乎是它的两倍
答案 0 :(得分:1)
我如何读取多个项一次,而不会在消息之间破坏因果关系?
确实很好。
如果确实以理想的方式执行,那么" 的TimeDOMAIN奇点"主要针对隐藏的形态表达为" 因果关系"。
与QUEUE-ingress一起给出,根据定义,它是纯粹的 [SERIAL]
(没有任何事情可能同时发生,只是纯粹的一个接一个,一个接一个,甚至如果"只是" - [CONCURENT]
调度可能会暴露给外部代理,内部QUEUE管理符合消息内部流和交付的纯顺序排序(也参考时间戳,持久性和其他人工制品))。
因果关系也意味着一些事件的 cause -> effect
排序,无论是在关系的抽象因果关系中,还是在事物的实时流程中事实上确实发生了,所以实际上是" 的反模式"。
最后但并非最不重要的是,因果关系还必须处理其他范例, cause ->
方之间的延迟和 -> effect
一侧(通常 F inite- S tate- A utomata,通常拥有比仅仅{ 0 -> CREATE -> UPDATE [ -> UPDATE [...] ] -> }
系列事件更丰富的状态空间。
结果
虽然有人可以阅读"使用某种程度的[CONCURRENT]
- 进程安排,FSA /因果关系条件主要避免移动到主要的纯 [SERIAL]
后处理事件消息。
如果消息传递框架是无代理的,并且没有保证对丢失的消息/消息排序/消息真实性/消息内容的稳健性,那么就会有更多的要求。
Devils开始反对您构建一致,分布式事务处理强大,分布式FSA的尝试:o)