amq筆記:記一個關於PooledConnectionFactory的問題

替人排查一個關於amq鏈接數的問題,使用PooledConnectionFactory進行鏈接池管理,設置了鏈接數上限爲3,但部署到服務器以後,瞬間創建了幾百個鏈接,用netstat -an 查看,發現大部分到amq服務器的鏈接狀態都是TIME_WAIT。服務器

初始化鏈接池:session

     ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
        ActiveMQPrefetchPolicy activeMQPrefetchPolicy = new ActiveMQPrefetchPolicy();

        activeMQConnectionFactory.setPrefetchPolicy(activeMQPrefetchPolicy);

        activeMQConnectionFactory.setUserName("XXX");
        activeMQConnectionFactory.setPassword("XXXX");
        activeMQConnectionFactory.setUseAsyncSend(true);
        activeMQConnectionFactory
                .setBrokerURL("failover:(tcp://XXXXX:XXXXX,tcp://XXXXX:XXXXX)?randomize=true");

        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(
                activeMQConnectionFactory);
        pooledConnectionFactory.setMaximumActiveSessionPerConnection(10);
        pooledConnectionFactory.setMaxConnections(3);

 

發消息:dom

        try {
            MessageProducer producer = null;

            connection = pooledConnectionFactory.getConnectionFactory().createConnection();//此句大霧

            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Destination destination = session
                    .createQueue("XXXXX");
            producer = session.createProducer(destination);
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

            connection.start();
            TextMessage message = session.createTextMessage(sMessage);
            producer.send(message);

        } finally {
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();

            }
        }

用盡各類關鍵詞都找不到類似的問題描述,最後仍是從代碼下手,發現connection = pooledConnectionFactory.getConnectionFactory().createConnection();這一句用法比較怪異。最大鏈接數屬性是針對pooledConnectionFactory設置的,pooledConnectionFactory自己有createConnection方法,爲何還要把裏面的connectionFactory取出來再建立呢?tcp

進代碼裏看,發現原來的代碼引用的方法是取出鏈接池中的activeMQConnectionFactory後直接新建鏈接,調用close方法時關閉,根據TCP的工做原理,主動關閉的鏈接會保持一段時間的TIME_WAIT狀態再行完全關閉。而pooledConnectionFactory的createConnection纔是在進行鏈接池管理。所以,只要把建立鏈接的那句代碼改成connection = pooledConnectionFactory.createConnection();就能夠解決這個問題。fetch

相關文章
相關標籤/搜索