Spring CachingConnectionFactory限制频道&导致线程阻塞

时间:2017-06-26 20:47:10

标签: java multithreading rabbitmq messaging spring-rabbit

我有一个简单的消息发布者以非常高的速度发布到rabbitmq(本地)。

ExecutorService threadPool = Executors.newFixedThreadPool(5, factory);

for (int i = 1; i <= 1000000; i++) {
    int finalI = i;
    threadPool.submit(new Runnable() {
        @Override
        public void run() {
            messagePublisher.publishMessage("testExchange", "testRoutingKey1", message + String.valueOf(finalI));
        }
    });
}

这里messagePublisher是以下类的实例

public class ChannelCachedMessagePublisher {

    private static CachingConnectionFactory CACHING_CONNECTION_FACTORY = new CachingConnectionFactory("localhost");
    private static RabbitTemplate RABBIT_TEMPLATE;

    private void init() {
        if (!INITIALIZED) {
            synchronized (ConnectionCachedMessagePublisher.class) {
                CACHING_CONNECTION_FACTORY.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
                CACHING_CONNECTION_FACTORY.setChannelCacheSize(100);
                CACHING_CONNECTION_FACTORY.setVirtualHost("testVHost");
                CACHING_CONNECTION_FACTORY.setConnectionNameStrategy(CACHING_CONNECTION_FACTORY -> "arpit-cached-connection");
                CACHING_CONNECTION_FACTORY.setPublisherConfirms(false);
                RABBIT_TEMPLATE = new RabbitTemplate(CACHING_CONNECTION_FACTORY);
            }
            INITIALIZED = true;
        }
    }

    public void publishMessage(String exchange, String routingKey, String message) {

        RABBIT_TEMPLATE.convertAndSend(exchange, routingKey, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                MessageProperties properties = message.getMessageProperties();
                properties.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                return new org.springframework.amqp.core.Message(message.getBody(),properties);
            }
        });
    }
}

执行此代码后,5个线程在单个连接上仅创建5个通道。

编辑1 1)。为什么连接工厂在这里不提供超过5个线程并且每个线程关联线程? 这部分现在很清楚,因为连接工厂无法提供更多的通道(或连接),而不是运行线程本身的数量。

接下来,立即所有线程开始被SocketFrameHandler中的监视器对象阻塞。

  

&#34; arpit-RMQ-5&#34; #1019 prio = 5 os_prio = 31 tid = 0x00007fb90c5b8800   nid = 0x83303等待监视器输入[0x0000700047bca000]
  java.lang.Thread.State:BLOCKED(在对象监视器上)           在com.rabbitmq.client.impl.SocketFrameHandler.writeFrame(SocketFrameHandler.java:170)

Here's a view of the threads post execution exit

2)。为什么这些线程确实被阻塞,解决这些问题的解决方法是什么?

注意:这导致我的兔子连接处于流量控制状态,我很好。我主要担心的是JVM中的线程阻塞。

0 个答案:

没有答案