簡體   English   中英

Jms-ActiveMQ TOPIC慢消費者

[英]Jms-ActiveMQ TOPIC slow consumer

我正在使用一個持久性主題,其中生產者使用以下策略發布事件:

   <bean id="jmsTemplateESB"   class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory"     ref="cachedJmsConnectionFactory" />
    <property name="defaultDestination" ref="activeMQTopic" />
    <!-- Value = javax.jms.DeliveryMode.PERSISTENT -->
    <property name="deliveryMode" value="2" />
    <!-- Value = javax.jms.Session.AUTO_ACKNOWLEDGE -->
    <property name="sessionAcknowledgeMode" value="1" />
    <!-- Needs to be true for the deliveryMode to work -->

    <property name="explicitQosEnabled" value="true" />
    </bean>

我正在為消費者使用以下設置:

   public static void listenOnTopic(String topicName, MessageListener listener) 
   throws Exception 
   {
   ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(bindAddress);
   Connection con = factory.createConnection();


   con.setClientID("Consumer");
   Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
   Topic topic = session.createTopic(topicName);
   TopicSubscriber subscriber = session.createDurableSubscriber(topic, listener.getClass().getName());

   subscriber.setMessageListener(listener);

   con.start();
  }

使用下面的監聽器

public class ActiveMQMessageListener implements MessageListener
{
 private static final Logger LOG = LoggerFactory.getLogger(ActiveMQMessageListener.class);

 @Autowired
 @Qualifier("jmsEventOutPutChannel")
 MessageChannel outputChannel;

 @Override
 public void onMessage(Message message) {
    try {   
        BytesMessage bytesMessage= (BytesMessage) message;
        byte[] data = new byte[(int)bytesMessage.getBodyLength()];
        bytesMessage.readBytes(data);
        org.springframework.integration.Message<byte[]> outputMessage = MessageBuilder.withPayload(data).build();
        outputChannel.send(outputMessage);
    } catch (JMSException e) {
        e.printStackTrace();
        LOG.error("Error while retrieving events from ActiveMQ ",e);
    }
 }
}

並遵循輸出通道的彈簧設置

    <bean id="callerBlockPolicy" class="org.springframework.integration.util.CallerBlocksPolicy">
    <constructor-arg type="long" value="10000"></constructor-arg>
</bean>

<bean id="jmsListnerTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="${CORE_POOL_SIZE}"></property>
    <property name="maxPoolSize" value="${THREAD_POOL_SIZE_JMS_LISTENER}"></property>
    <property name="queueCapacity" value="${QUEUE_SIZE_JMS_LISTENER}"></property>
    <property name="rejectedExecutionHandler" ref="callerBlockPolicy"></property>
    <property name="waitForTasksToCompleteOnShutdown" value="true"></property>
</bean>

<int:channel id="jmsEventOutPutChannel">
    <int:dispatcher task-executor="jmsListnerTaskExecutor" />
</int:channel>

此使用者代碼太慢,以至於我們無法從主題快速檢索消息。

實際上,沒有圖片中的“ jmsEventOutPutChannel”,我得到的速率約為9500 qps,但是有圖片中的“ jmsEventOutPutChannel”,我得到的速率卻要少得多,約為150 qps。

有人能暗示我這段代碼在做什么嗎?

我的“ jmsEventOutPutChannel”通道代碼是否也會影響activeMQ的消耗率?

問題實際上不是您的使用者代碼,而是將消息發送到輸出通道時出了點問題。

集中在那里,看看為什么消息需要這么長時間才能寫入ActiveMQ。 首先,我嘗試使其變為非持久性(但仍然持久),然后觀察其行為是否有所不同。 可能是ActiveMQ服務器的配置不正確,並且寫入后端存儲的效率很低(也許Kahadb無法跟上?)

生產者是否有可能為發送的每個消息創建連接,而開銷卻使您喪命?

您可能會發布ActiveMQ URL,但不知道添加了哪些參數可能會有所不同。 但是,看到它這么嚴重地退化顯然是不好的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM