春天jms听众消费者规模不会下降

时间:2016-06-10 15:36:33

标签: spring jms listener limit

enter image description here我有以下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;
    }
}

SOAReportGeneration.java

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;
    }

1 个答案:

答案 0 :(得分:0)

你真的是指13560名消费者吗?我希望这是一个错字。

为了回答您的问题,Spring JMS doc明确指出在运行时可以忽略指定的最小消费者数量。见下文:

  

为每个侦听器启动的并发会话/使用者数。可以是表示最大数字的简单数字(例如“5”)或表示较低数字和上限的范围(例如“3-5”)。 请注意,指定的最小值只是一个提示,可能会在运行时忽略。默认值为1;在主题监听器或队列排序很重要的情况下,将并发性限制为1;考虑将其提升为一般队列。