Concurrent Strategies using MDBs – 使用MDB的并发策略

最后修改: 2018年 8月 8日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

Message Driven Beans, also known as “MDB”, handle message processing in an asynchronous context. We can learn the basics of MDB in this article.

消息驱动Bean,也被称为 “MDB”,在异步环境下处理消息。我们可以在这篇文章中了解MDB的基本知识

This tutorial will discuss some strategies and best practices to implement concurrency using Message Driven Beans.

本教程将讨论使用消息驱动Bean实现并发的一些策略和最佳实践。

If you want to understand more about the basics of concurrency using Java, you can get started here.

如果你想了解更多关于使用Java并发的基础知识,你可以从这里开始

In order to better use MDBs and concurrency, there are some considerations to make. It’s important to keep in mind that those considerations should be driven by the business rules and the needs of our application.

为了更好地使用MDB和并发性,需要进行一些考虑。重要的是要记住,这些考虑因素应该由业务规则和我们应用程序的需求驱动。

2. Tuning the Thread Pool

2.调整线程池

Tuning the Thread Pool is probably the main point of attention. To make a good use of concurrency, we must tune the number of MDB instances available to consume messages. When one instance is busy handling a message, other instances are able to pick up the next ones.

调整线程池可能是主要的关注点。为了很好地利用并发性,我们必须调整可用于消费消息的MDB实例的数量。当一个实例忙于处理一个消息时,其他实例就能接上下一个。

The MessageListener thread is responsible to execute the onMessage method of an MDB. This thread is part of the MessageListener thread pool, which means that it’s pooled and reused over and over again. This pool also has a configuration that allows us to set the number of threads, which may impact the performance:

MessageListener线程负责执行一个MDB的onMessage方法。这个线程是MessageListener线程池的一部分,这意味着它被汇集在一起并被反复使用。这个池子也有一个配置,允许我们设置线程的数量,这可能会影响到性能:

  • setting a small pool size will cause messages to be consumed slowly (“MDB Throttling”)
  • setting a very large pool size might decrease performance – or not even work at all.

On Wildfly, we can set this value by accessing the management console. JMS capability isn’t enabled on the default standalone profile; we need to start the server using the full profile.

Wildfly上,我们可以通过访问管理控制台来设置这个值。JMS功能没有在默认的独立配置文件中启用;我们需要使用完整配置文件启动服务器。

Usually, on a local installation, we access it through http://127.0.0.1:9990/console/index.html. After that, we need to access Configuration / Subsystems / Messaging / Server, select our server and click “View”.

通常,在本地安装的情况下,我们通过http://127.0.0.1:9990/console/index.html。之后,我们需要访问配置/子系统/消息传递/服务器,选择我们的服务器并点击 “查看”。

Choose the “Attributes” tab, click on “Edit” and change the value of “Thread Pool Max Size”. The default value is 30.

选择 “属性 “标签,点击 “编辑”,改变 “线程池最大尺寸 “的值。默认值是30。

3. Tuning Max Sessions

3.调整最大限度的会议

Another configurable property to be aware of is Maximum Sessions. This defines the concurrency for a particular listener port. Usually, this defaults to 1 but increasing it can give more scalability and availability to the MDB application.

另一个需要注意的可配置属性是最大会话。这定义了一个特定监听器端口的并发性。通常,它的默认值是1,但增加它可以为MDB应用程序提供更多的可扩展性和可用性。

We can configure it either by annotations or .xml descriptors. Through annotations, we use the @ActivationConfigProperty:

我们可以通过注释或.xml描述符来配置它。通过注解,我们使用@ActivationConfigProperty

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(
        propertyName=”maxSession”, propertyValue=”50”
    )
})

If the chosen method of configuration is .xml descriptors we can configure maxSession like this:

如果选择的配置方法是.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. Deployment Environment

4.部署环境

When we have a requirement for high availability, we should consider deploying the MDB on an application server cluster. Thus, it can execute on any of the servers in the cluster and many application servers can invoke it concurrently, which also improves scalability.

当我们有高可用性的要求时,我们应该考虑将MDB部署在一个应用服务器集群上。因此,它可以在集群中的任何一个服务器上执行,许多应用服务器可以并发地调用它,这也提高了可扩展性。

For this particular case, we have an important choice to make:

对于这个特殊的案例,我们要做一个重要的选择。

  • make all servers in the cluster eligible to receive messages, which allows the use of all of its processing power, or
  • ensure message processing in a sequential manner by allowing just one server to receive them at a time

If we use an enterprise bus, a good practice is to deploy the MDB to the same server or cluster as the bus member to optimize the messaging performance.

如果我们使用企业总线,一个好的做法是将MDB部署到与总线成员相同的服务器或集群,以优化消息传递性能。

5. Message Model and Message Types

5.消息模型和消息类型

Although this isn’t as clear as just setting another value to a pool, the message model and the message type might affect one of the best advantages of using concurrency: performance.

虽然这并不像只是给池子设置另一个值那么清楚,但消息模型和消息类型可能会影响到使用并发性的最佳优势之一:性能。

When choosing XML for a message type, for instance, the size of the message can affect the time spent to process it. This is an important consideration especially if the application handles a large number of messages.

例如,在为消息类型选择XML时,消息的大小会影响处理它所花费的时间。这是一个重要的考虑因素,尤其是在应用程序处理大量消息的情况下。

Regarding the message model, if the application needs to send the same message to a lot of consumers, a publish-subscribe model might be the right choice. This would reduce the overhead of processing the messages, providing better performance.

关于消息模型,如果应用程序需要向许多消费者发送相同的消息,发布-订阅模型可能是正确的选择。这将减少处理消息的开销,提供更好的性能。

To consume from a Topic on a publish-subscribe model, we can use annotations:

为了从发布-订阅模式的Topic中消费,我们可以使用注释。

@ActivationConfigProperty(
  propertyName = "destinationType", 
  propertyValue = "javax.jms.Topic")

Again, we can also configure those values in a .xml deployment descriptor:

同样,我们也可以在.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>

If sending the very same message to many consumers isn’t a requirement, the regular PTP (Point-to-Point) model would suffice.

如果向许多消费者发送非常相同的信息不是一个要求,常规的PTP(点对点)模式就足够了。

To consume from a Queue, we set the annotation as:

为了从队列中消费,我们将注解设置为。

@ActivationConfigProperty(
  propertyName = "destinationType", 
  propertyValue = "javax.jms.Queue")

If we’re using .xml deployment descriptor, we can set it:

如果我们使用.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>

6. Conclusion

6.结论

As many computer scientists and IT writers already stated, we no longer have processors’ speed increasing on a fast pace. To make our programs work faster, we need to work with the higher number of processors and cores available today.

正如许多计算机科学家和IT作家已经指出的那样,我们的处理器速度不再快速增长。为了使我们的程序工作得更快,我们需要与当今更多数量的处理器和内核一起工作。

This article discussed some best practices for getting the most out of concurrency using MDBs.

这篇文章讨论了使用MDB获得最大并发性的一些最佳实践。