Wildfly14部署Spring Boot WAR后JmsListener并发配置不生效如何解决
Spring Boot部署WildFly 14后@JmsListener并发参数失效解决方案
该问题核心原因是Spring
@JmsListener的concurrency参数在WildFly容器环境下会被WildFly内置的EJB3 MDB实例池、JMS资源适配器的默认配置覆盖。WildFly对未显式指定池的MDB默认使用default-strict-max-pool,该池默认最大实例数为1,因此Spring侧配置的5个并发不会生效,而独立启动时Spring使用内置连接池和线程池,不受容器配置限制所以可以正常生效。
方案1:绑定自定义bean-instance-pool(适配你预设的池配置)
你可以将JMS消费类改造为兼容JEE规范的MDB,通过注解或XML绑定你提前配置的individual-strict-max-pool,步骤如下:
- 调整消费类注解,新增EJB相关注解:
import javax.ejb.MessageDriven; import org.jboss.ejb3.annotation.Pool; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import javax.jms.Message; @Component @MessageDriven @Pool(value = "individual-strict-max-pool") public class JmsMessageConsumer { public static final String JMS_MESSAGE_NAME = "你的队列名"; @JmsListener(destination = JMS_MESSAGE_NAME, concurrency = "5") public void receiveFromMessageQueue(Message msg) { // 你的业务处理逻辑 } }
- 在项目
WEB-INF目录下新增jboss-ejb3.xml配置,保证池绑定规则生效:
<?xml version="1.0" encoding="UTF-8"?> <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd"> <assembly-descriptor> <ejb-pool> <ejb-name>JmsMessageConsumer</ejb-name> <pool-ref>individual-strict-max-pool</pool-ref> </ejb-pool> </assembly-descriptor> </jboss:ejb-jar>
方案2:使用Spring独立管理的JMS连接池(无需修改WildFly配置)
如果不想依赖WildFly的EJB池,可以在Spring上下文内自行配置独立的JMS连接工厂和监听器容器,完全绕开WildFly的资源管理,此时Spring侧的并发参数会直接生效:
- 新增JMS配置类:
import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.ActiveMQPrefetchPolicy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.connection.CachingConnectionFactory; import javax.jms.ConnectionFactory; import javax.jms.Session; @Configuration public class CustomJmsConfig { @Bean public ConnectionFactory independentJmsConnectionFactory() { // 替换为你实际使用的MQ连接配置,此处以ActiveMQ为例 ActiveMQConnectionFactory nativeFactory = new ActiveMQConnectionFactory(); nativeFactory.setBrokerURL("tcp://你的MQ服务地址:61616"); nativeFactory.setUserName("MQ账号"); nativeFactory.setPassword("MQ密码"); // 调整预取策略适配多并发消费 ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy(); prefetchPolicy.setQueuePrefetch(10); nativeFactory.setPrefetchPolicy(prefetchPolicy); return new CachingConnectionFactory(nativeFactory); } @Bean public DefaultJmsListenerContainerFactory independentJmsListenerFactory(ConnectionFactory independentJmsConnectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(independentJmsConnectionFactory); // 直接在此处配置并发数,注解处可省略concurrency参数 factory.setConcurrency("5"); factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE); return factory; } }
- 调整
@JmsListener注解,指定使用自定义的容器工厂:
@JmsListener(destination = JMS_MESSAGE_NAME, containerFactory = "independentJmsListenerFactory") public void receiveFromMessageQueue(Message msg) { // 业务逻辑 }
方案3:修改WildFly全局默认MDB池大小(不推荐)
如果不需要为单个监听器独立配置池,也可以直接修改standalone.xml中默认MDB池的大小,该修改会影响所有部署在当前WildFly实例上的MDB:
<strict-max-pool name="default-strict-max-pool" max-pool-size="5" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
内容的提问来源于stack exchange,提问作者Benjamin Schüller
相关产品推荐
相关产品推荐

