使用MDB的并发策略
1. 简介
消息驱动 Bean,也称为“MDB”,在异步上下文中处理消息。我们可以在本文 中学习 MDB 的基础知识。
本教程将讨论使用消息驱动 Bean 实现并发的一些策略和最佳实践。
如果您想了解更多关于使用 Java 并发的基础知识,您可以从这里 开始。
为了更好地使用 MDB 和并发性,需要考虑一些事项。重要的是要记住,这些考虑应该由业务规则和我们的应用程序的需求驱动。
2. 调优线程池
调整线程池可能是主要关注点。为了充分利用并发性,我们必须调整可用于消费消息的 MDB 实例的数量。当一个实例忙于处理消息时,其他实例能够接听下一个实例。
MessageListener线程负责执行MDB 的onMessage方法。该线程是MessageListener 线程池的一部分,这意味着它被池化并一遍又一遍地重用。这个池还有一个配置,允许我们设置线程数,这可能会影响性能:
- 设置较小的池大小会导致消息消耗缓慢(“MDB Throttling”)
- 设置一个非常大的池大小可能会降低性能——甚至根本不起作用。
在Wildfly 上,我们可以通过访问管理控制台来设置这个值。默认独立配置文件上未启用 JMS 功能;我们需要使用完整的配置文件启动服务器。
通常,在本地安装中,我们通过 http://127.0.0.1:9990/console/index.html 访问它。之后,我们需要访问配置/子系统/消息/服务器,选择我们的服务器并单击“查看”。
选择“属性”选项卡,单击“编辑”并更改“线程池最大大小”的值。默认值为 30。
3. 调整最大会话数
另一个需要注意的可配置属性是Maximum Sessions。这定义了特定侦听器端口的并发性。通常,这默认为 1,但增加它可以为 MDB 应用程序提供更多的可伸缩性和可用性。
我们可以通过注解或*.xml描述符来配置它。通过注解,我们使用@ActivationConfigProperty*:
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName=”maxSession”, propertyValue=”50”
)
})
如果选择的配置方法是*.xml描述符,我们可以像这样配置maxSession*:
<activation-config>
<activation-config-property>
<activation-config-property-name>maxSession</activation-config-property-name>
<activation-config-property-value>50</activation-config-property-value>
</activation-config-property>
</activation-config>
4. 部署环境
当我们对高可用性有要求时,我们应该考虑将 MDB 部署在应用服务器集群上。因此,它可以在集群中的任何服务器上执行,并且许多应用程序服务器可以同时调用它,这也提高了可伸缩性。
对于这种特殊情况,我们有一个重要的选择:
- 使集群中的所有服务器都有资格接收消息,这允许使用其所有处理能力,或者
- 通过一次只允许一台服务器接收 消息,确保按顺序处理消息
如果我们使用企业总线,一个好的做法是将 MDB 部署到与总线成员相同的服务器或集群中,以优化消息传递性能。
5. 消息模型和消息类型
尽管这不像为池设置另一个值那么清楚,但消息模型和消息类型可能会影响使用并发的最大优势之一:性能。
例如,在为消息类型选择 XML 时,消息的大小会影响处理它所花费的时间。这是一个重要的考虑因素,尤其是在应用程序处理大量消息时。
关于消息模型,如果应用程序需要向很多消费者发送相同的消息,那么发布-订阅模型可能是正确的选择。这将减少处理消息的开销,提供更好的性能。
要从发布订阅模型上的Topic消费,我们可以使用注解:
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Topic")
同样,我们还可以在*.xml*部署描述符中配置这些值:
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Topic</activation-config-property-value>
</activation-config-property>
</activation-config>
如果不需要向许多消费者发送相同的消息,那么常规的 PTP(点对点)模型就足够了。
要从队列中消费,我们将注解设置为:
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
如果我们使用 .xml部署描述符,我们可以设置它:
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
</activation-config-property>
</activation-config>