Springboot JMS LIstener ActiveMQ非常慢

时间:2016-12-04 15:10:08

标签: spring spring-boot jms activemq spring-jms

我有一个SpringBoot应用程序,它使用来自ActiveMQ Queue的自定义可序列化消息。到目前为止,它的工作效果非常差,只有1 - 20 msg / sec。

@JmsListener(destination = "${channel.consumer.destination}", concurrency="${channel.consumer.maxConcurrency}")
public void receive(IMessage message) {
    processor.process(message);
}

以上是我的渠道消费者类的片段,它有一个处理器实例(注入,自动装配,在其中我有@Async服务,所以我可以假设主要线程将在消息进入@Async方法时立即释放)和它还使用我从应用程序属性

设置的springboot activemq默认conn工厂
# ACTIVEMQ (ActiveMQProperties)
spring.activemq.broker-url= tcp://localhost:61616?keepAlive=true
spring.activemq.in-memory=true
spring.activemq.pool.enabled=true
spring.activemq.pool.expiry-timeout=1
spring.activemq.pool.idle-timeout=30000
spring.activemq.pool.max-connections=50

很少值得通知:
1.我在本地笔记本电脑上运行所有东西(Eclipse,ActiveMQ,MYSQL) 2.在此之前,我还尝试使用配备自定义线程池任务执行程序的自定义连接工厂(默认AMQ,池和缓存),但仍然得到相同的结果。下面是我拍摄的快照性能捕获,每1秒更新一次 我还在JVM Monitor中告知使用的堆继续递增

My JVM Monitor Instance

Performance Counter Snapshot


我想知道:
1.我的步骤中是否有错误/缺失?我的消息率中甚至无法触及数百 2.带注释的@JmsListener方法将执行进程异步或同步?
3.如果可能并且支持,如何正确和优雅地使用传统的sync receive()和SpringBoot?

谢谢

1 个答案:

答案 0 :(得分:0)

我只是在检查类似的东西。我在我的JMSConfiguration类(Spring配置)中定义了DefaultJmsListenerContainerFactory,如下所示:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(CachingConnectionFactory connectionFactory) {

    // settings made based on https://bsnyderblog.blogspot.sk/2010/05/tuning-jms-message-consumption-in.html
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(){
        @Override
        protected void initializeContainer(DefaultMessageListenerContainer container) {
            super.initializeContainer(container);
            container.setIdleConsumerLimit(5);
            container.setIdleTaskExecutionLimit(10);
        }
    };
    factory.setConnectionFactory(connectionFactory);
    factory.setConcurrency("10-50");
    factory.setCacheLevel(CACHE_CONSUMER);
    factory.setReceiveTimeout(5000L);
    factory.setDestinationResolver(new BeanFactoryDestinationResolver(beanFactory));
    return factory;
}

如您所见,我从https://bsnyderblog.blogspot.sk/2010/05/tuning-jms-message-consumption-in.html获取了这些值。这是从2010年开始,到目前为止我找不到更新/更好的东西。

我还将Spring的CachingConnectionFactory Bean定义为ConnectionFactory:

@Bean
public CachingConnectionFactory buildCachingConnectionFactory(@Value("${activemq.url}") String brokerUrl) {
    // settings based on https://bsnyderblog.blogspot.sk/2010/02/using-spring-jmstemplate-to-send-jms.html
    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    activeMQConnectionFactory.setBrokerURL(brokerUrl);
    CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(activeMQConnectionFactory);
    cachingConnectionFactory.setSessionCacheSize(10);
    return cachingConnectionFactory;
}

此设置将帮助JmsTemplate发送。

所以我的回答是设置连接池的值,如链接中所述。另外我猜你可以删除spring.activemq.in-memory = true,因为(基于文档)如果你指定自定义代理URL,则会忽略“内存中”属性。

如果这有帮助,请告诉我。

-G。