spring jms侦听器使用者大小不为';不要下去

spring jms侦听器使用者大小不为';不要下去,spring,jms,listener,limit,Spring,Jms,Listener,Limit,我有下面的SpringJMS侦听器配置来处理大量消息。当有超过200条消息到达时,它能够处理所有消息而不出现任何错误,并且在查看JMX控制台时,它显示大约13560个消费者正在处理消息。但是,在处理完所有消息(即处理完成)后,消费者的数量不会下降,而是显示相同的数量。有人能告诉我是什么原因吗?我是否缺少任何配置或代码 <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <p

我有下面的SpringJMS侦听器配置来处理大量消息。当有超过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>

你真的是说13560名消费者吗?我希望这是一个打字错误

为了回答您的问题,请明确说明在运行时可以忽略指定的最小使用者数。见下文:

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


你真的是说13560名消费者吗?我希望这是一个打字错误

为了回答您的问题,请明确说明在运行时可以忽略指定的最小使用者数。见下文:

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


用JMX控制台中显示的消费者数量编辑了我的答案。这个数字是我在同一时间丢弃了大约300条消息进行处理时的数字。但这个数字仍然很大。不知道如何确保它限制了消费者的数量。这真的没有意义。因为您的spring配置将最大并发用户数设置为50;无论您在该队列中放置了多少条消息;与该队列关联的使用者数量不应超过50。您确定您看到的是正确的东西(收听此特定队列的消费者数量)吗?如果是的话,我很想通过使用PooledConnectionFactory而不是CachingConnectionFactory来查看行为。我没有使用ActiveMQ。我正在使用Jboss服务器,它使用HornetQ,我没有找到HornetQ的PooledConnectionFactory。我从JMX控制台获得了这个号码,如图所示。如果可以的话,我用更多的细节编辑了我的问题。我理解。那么你能试试spring的SingleConnectionFactory吗?这将导致大量IO开销,但最好排除使用CachingConnectionFactory导致此问题的可能性。另外,我们讨论的是一个消费者应用程序实例侦听此队列,还是有多个实例侦听同一个代理队列?我已经尝试使用SingleConnectionFactory,但没有看到任何更改。所以消费者应用程序是另一个应用程序(ESB),它有client.jar文件(即client jar有listener类),当前部署在与生产者(ESB)相同的服务器上,但我们也可以部署到其他服务器上。所以从实例角度来看,我认为,这是消费者应用程序的单个实例。这个数字是我在同一时间丢弃了大约300条消息进行处理时的数字。但这个数字仍然很大。不知道如何确保它限制了消费者的数量。这真的没有意义。因为您的spring配置将最大并发用户数设置为50;无论您在该队列中放置了多少条消息;与该队列关联的使用者数量不应超过50。您确定您看到的是正确的东西(收听此特定队列的消费者数量)吗?如果是的话,我很想通过使用PooledConnectionFactory而不是CachingConnectionFactory来查看行为。我没有使用ActiveMQ。我正在使用Jboss服务器,它使用HornetQ,我没有找到HornetQ的PooledConnectionFactory。我从JMX控制台获得了这个号码,如图所示。如果可以的话,我用更多的细节编辑了我的问题。我理解。那么你能试试spring的SingleConnectionFactory吗?这将导致大量IO开销,但最好排除使用CachingConnectionFactory导致此问题的可能性。另外,我们讨论的是一个消费者应用程序实例侦听此队列,还是有多个实例侦听同一个代理队列?我已经尝试使用SingleConnectionFactory,但没有看到任何更改。所以消费者应用程序是另一个应用程序(ESB),它有client.jar文件(即client jar有listener类),当前部署在与生产者(ESB)相同的服务器上,但我们也可以部署到其他服务器上。所以从实例角度来看,我认为,它是消费者应用程序的单个实例。
<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>
    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;
    }