我有以下spring jms监听器配置来处理大量消息。当有超过200条消息到达时,它能够处理所有没有任何错误的消息,并且在查看JMX控制台时,它显示大约13560个消费者活动处理消息。然而,在处理完所有消息(即完成处理)之后,消费者的数量不会下降,它显示相同的数字。有人能告诉我可能是什么原因吗?我错过了任何配置或代码吗?
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">${PROVIDER.URL}</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
</props>
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="jndiName" value="/ConnectionFactory" />
</bean>
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory" >
<property name="targetConnectionFactory">
<ref bean="connectionFactory" />
</property>
<property name="sessionCacheSize" value="5"/>
<!-- <property name="reconnectOnException" value="true" /> -->
</bean>
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="cache" value="true" />
</bean>
<jms:listener-container connection-factory="jmsQueueConnectionFactory"
destination-type="queue"
destination-resolver="jmsDestinationResolver"
error-handler="errorHandler"
acknowledge="auto"
concurrency="10-50"
cache="consumer">
<jms:listener destination="${REMOTE.REQUEST.QUEUE}"
ref="reportGenerationMessageDelegate"
selector="messageType = '${PDF.REPORT.MESSAGE.TYPE}' OR
messageType = '${CSV.REPORT.MESSAGE.TYPE}'" />
</jms:listener-container>
所以目前的设计如下: 1.我有Jboss esb服务类,它在RequestQueue上发送消息并等待ResponseQueue上的响应。这是类
的配置<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">${JMS.server.URL}</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
</props>
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="jndiName" value="/ConnectionFactory" />
</bean>
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplate" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destinationResolver" ref="jmsDestinationResolver" />
</bean>
监听器类配置如下:
SOAReportGenreation类扩展了接收消息的AbstractRemoteRequestListener类
public abstract class AbstractRemoteRequestListener {
/**
* Method processMessage.
* @param message ObjectMessage
* @return String
* @throws JMSException
* @throws Exception
*/
public abstract String processMessage(ObjectMessage message) throws JMSException, Exception;
/**
* Method handleMessage.
* @param message ObjectMessage
* @return String
* @throws JMSException
* @throws Exception
*/
@SuppressWarnings("unchecked")
public String consumeMessage(ObjectMessage message) throws JMSException, Exception{
try {
if (message != null) {
l.info("Message received for messageType= "+ message.getStringProperty("messageType"));
Map<String, Object> map = (HashMap<String, Object>) message.getObject();
return processMessage(message);
}
} catch (Exception e) {
L.error(e);
}
return null;
}
}
public class SOAReportGeneration extends AbstractRemoteRequestListener{
private static final Logger L = Logger.getLogger(SOAReportGeneration.class);
private static ApplicationContext context;
@Override
public String processMessage(ObjectMessage message) throws JMSException, Exception {
if(context == null){
context = new ClassPathXmlApplicationContext("serviceContext.xml");
}else{
L.info("using already initialized spring context");
}
//business logic. i am loading service context to get bean definition
//and instantiate certain beans for business processing.
return null;
}
答案 0 :(得分:0)
你真的是指13560名消费者吗?我希望这是一个错字。
为了回答您的问题,Spring JMS doc明确指出在运行时可以忽略指定的最小消费者数量。见下文:
为每个侦听器启动的并发会话/使用者数。可以是表示最大数字的简单数字(例如“5”)或表示较低数字和上限的范围(例如“3-5”)。 请注意,指定的最小值只是一个提示,可能会在运行时忽略。默认值为1;在主题监听器或队列排序很重要的情况下,将并发性限制为1;考虑将其提升为一般队列。