繁体   English   中英

并行处理严格的消息

[英]Concurrent processing of messages with strict order

在我的JavaEE Web应用程序中,我需要严格按照到达顺序处理传入的消息。 我假设我的webapp容器(Tomcat 6)在到达http端口时保留了消息的顺序。

是什么让我头痛,是我在内部处理这些消息的方式。 为了改善工作量,我将每个消息的处理附加到ThreadPool,因为这里需要做很多事情,例如XML解析,有时使用外部Web服务来丰富数据。 处理完成后,我将消息的java表示推送到复杂的流处理引擎esper.codehaus.org ,这是线程安全的。 这里,检查不同的模式,其中入口顺序是最高要求,例如现象的阈值超过。

我有想法将每个已处理的消息插入到PriorityQueue中,并在到达时收到优先级ID(在我的Servlet中,每个消息都会递增)。 问题如下:

从队列中轮询元素(最低ID是队列的头部)以将其插入esper的线程可以跳过ID,因为它不检查丢失的项目。 我猜插图效果更好:

在此输入图像描述

对于步骤(1)至(4),一切都按预期工作。 但是在步骤(5),QueuePoller检索元素6而不是元素4(稍后在步骤(6)插入)。 这导致消息顺序:2; 3; 6; 4。

我试图做的是改变轮询队列头部的实现,以遵循严格的ID顺序。 这意味着,如果下一个ID的元素尚未插入队列,则在屏障处等待直到其中。 这似乎在前10分钟有效但随后被绞死,可能是由于一个从未插入队列的元素。

过去有过类似问题的人对我有一些暗示吗?

查看Disruptor - 具有严格顺序的高性能队列(首次输入 - 首次服务)

您可以立即为处理队列中的传入请求添加占位符。 占位符在后台由线程池预处理,但主处理等待预处理完成。 我想到的构造是未来

类库提供了灵活的线程池实现以及一些有用的预定义配置。 您可以通过调用Executors中的一个静态工厂方法来创建线程池:

根据您的需要,我认为Executors.newSingleThreadExecutor()是最好的。 单线程执行程序创建一个工作线程来处理任务,如果它意外死亡则替换它。 保证任务按照任务队列(FIFO,LIFO,优先级顺序)强加的顺序依次处理。

正如您的问题和图表的需要所证明的那样(顺便说一句,+1)优先级队列不是您想要的好结构。 这是因为队列非常乐意为您提供可用的6而不是等待不可用的4。

我认为是时候推出自己的同步容器了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM