java-ee – 控制MDB中的并发和消耗

是否有任何标准方法来控制MDB中的并发和消耗?我能够找到的每个建议似乎都是应用服务器或资源适配器特定的(例如maxSession @ActivationConfigProperty).

问题™

我们在双节点JBoss设置(EAP 6.3)上运行一些相对繁重的分析工作,并希望并行化作业以及对并发作业数施加上限,因此我们不会淹没数据库服务器.作业是从Web前端启动的,应该在有免费处理槽时启动 – 没有优先级或排序约束.我们使用消息队列(IBM WMQ,因为政治)将“开始分析”消息分发给节点.

目前的进展

经过大量的调整,经过各种建议,结果证明是非工作资源 – 适配器特定的Cargo-Cult Misinformation™:),我认为问题是通过为MDB定义EJB池来解决的.这确实解决了并发问题,但不幸的是,似乎没有空闲MDB的节点仍然会拉取队列的消息 – 这可能会使一个节点未得到充分利用而另一个节点完全加载了积压.

如果我正确理解IBM documentation,则应使用readAheadAllowed配置选项控制此行为,但这似乎根本不会影响我的结果.

那么,有:

>一种控制消息消费的Java EE标准方法?
> A(工作)IBM WQ特定配置选项?
> JBoss特定的修复方法?
>其他一些我没有想过的智能解决方案?

或者,我可能会重新修改体系结构以使用主题队列,并让每个节点尝试UPDATE项目中的某些内容SET Status =’inprogress’WHERE Id = 42 AND St​​atus =’inqueue’; – 但是如果我没有,我宁愿不去那里,主要是因为改变队列所需的变更请求:)

最佳答案 MQ,实际上是JMS,经过精心设计和优化,尽可能快地将消息尽可能地传递到管道尽可能远的地方.队列管理器跟踪每个消息的状态,但并发要求将要求QMgr跟踪彼此相关的消息状态. MQ不这样做.

调整Activation Spec连接池和事务范围中的一些连接池有一些粒度,但这些粒度旨在影响服务器的动态行为,而不是精确指定它.

跨多个消息管理应用程序状态正是IBM Integration Broker等ESB产品的设计目标.虽然MQ是仅查看消息头以执行路由和传递的传输,但ESB会查看消息关系和内容.除非JMS规范定义了并发管理API,否则这种责任分工与MQ进行传输和ESB进行处理的可能性不大.

无论是在ESB还是JEE代码中实现,您所描述的都是Enterprise Integration Patterns中的Message Dispatcher Pattern,它是消息传递领域中权威的架构参考之一.根据仪器的偏好,有几种方法可以写这个.

符号化

>应用程序实例在令牌队列和同步点下等待执行GET.
>收到令牌消息后,应用程序再次在同步点下将相同的消息返回到令牌队列上.
>应用程序在同步点下的应用程序队列上执行GET并等待.
>收到应用程序消息后,应用程序将对其进行处理,然后根据需要执行COMMIT或ROLLBACK.

在处理应用消息之前,应用实例会竞争令牌消息.结果是app消息通常在它们到达时被处理得很快但在负载下最大并发等于令牌消息的数量.

通常,令牌消息是信息性的,例如包含随每次迭代递增的计数器以及可能写入令牌消息的最后一个应用的实例信息.这为正在发生的事情提供了一些诊断信息.在某些情况下,监控应用程序还会侦听令牌队列以对该信息进行采样并写入仪表板.在这种情况下,会向队列中添加额外的令牌消息,以说明监控应用程序的活动.

独立调度员

>调度程序应用程序在广告的目标队列上侦听消息,在ACK队列上侦听确认消息.
>计数器将未完成的消息与调度程序应用程序配置中设置的{max outstanding message limit}进行比较.
>如果未完成的消息 >当业务应用程序获取消息时,它还会向调度程序的ACK队列发送一条消息,这两个操作都在同步点下.
>当业务应用程序发出COMMIT时,调度程序接收ACK并减少未完成的消息计数器.

调度程序应用程序可以请求确认传递消息,但这些消息并不总是与成功处理事务的业务应用程序相关联.如果业务应用程序明确地将ACK消息放在与消耗的业务消息相同的工作单元中,那么结果是坚如磐石的.

点赞