替人排查一個關於amq連接數的問題,使用PooledConnectionFactory進行連接池管理,設置了連接數上限為3,但部署到服務器之后,瞬間建立了幾百個連接,用netstat -an 查看,發現大部分到amq服務器的連接狀態都是TIME_WAIT。
初始化連接池:
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);
發消息:
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取出來再創建呢?
進代碼里看,發現原來的代碼引用的方法是取出連接池中的activeMQConnectionFactory后直接新建連接,調用close方法時關閉,根據TCP的工作原理,主動關閉的連接會保持一段時間的TIME_WAIT狀態再行徹底關閉。而pooledConnectionFactory的createConnection才是在進行連接池管理。因此,只要把創建連接的那句代碼改為connection = pooledConnectionFactory.createConnection();就可以解決這個問題。