[英]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.