替人排查一個關於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