获得的经验:ActiveMQ,Apache Camel和连接池
每隔一段時間,我會遇到一個與ActiveMQ的連接和池相關的有趣問題,而今天,我想討論一些并不總是很清楚的問題,并且在使用ActiveMQ和Camel JMS時可能會導致您大量飲酒。 并不是說您無論如何都不會在使用ActiveMQ和Camel時大量喝酒……以慶祝使用它們時集成和消息傳遞變得多么令人愉快。
所以首先。 連接池。
當然,您總是聽說過要建立連接。 這到底是什么意思,為什么要這么做?
與創建會話或使用方等其他操作相比,打開與ActiveMQ代理的連接是一項相對昂貴的操作。 因此,在發送或接收消息并通常與代理進行交互時,如果可能的話,您希望重用現有的連接。 您不需要做的就是依靠JMS庫(例如Spring JmsTemplate),該庫在每次發送或接收消息時都會打開和關閉連接……除非您可以合并/緩存連接。
因此,如果我們可以同意池化連接是一個好主意,請看一個示例配置:
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop"><property name="maxConnections" value="10" /><property name="maximumActiveSessionPerConnection" value="10" /><property name="connectionFactory" ><bean class="org.apache.activemq.ActiveMQConnectionFactory"><property name="brokerURL" value="tcp://127.0.0.1:61616" /></bean></property></bean>您甚至可能要使用Apache Camel及其出色的camel-jms組件,因為否則這樣做很愚蠢。 因此,也許您想要設置類似于以下內容的JMS配置:
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"><property name="connectionFactory" ref="pooledConnectionFactory" /><property name="transacted" value="true" /><property name="concurrentConsumers" value="15" /><property name="deliveryPersistent" value="true" /><property name="requestTimeout" value="10000" /><property name="cacheLevelName" value="CACHE_CONSUMER" /></bean>此配置基本上對消費者意味著,設置15個并發消費者,使用事務(本地),對生產者使用PERSISTENT消息,將超時設置為10000以進行請求答復等。
值得注意的是 :如果您想更全面地了解jms組件的配置,尤其是在緩存使用者,事務等方面,請參考Torsten關于Camel JMS 的出色的博客, 其中包含交易-經驗教訓 。 也許您還應該花一些時間在他的博客上閑逛,因為他也有很多很好的Camel / ActiveMQ東西!
到目前為止很棒。 我們有一個包含10個連接的連接池,我們希望每個連接10個會話(如果需要,總共100個會話…),以及15個并發使用者。 我們應該能夠應付一些沉重的負擔,對不對?
在這里看看這條路線。 這很簡單,公開了activemq組件(它將使用上面的jmsConfig,因此有15個并發使用者)并僅執行一些日志記錄:
from("activemq:test.queue").routeId("test.queue.routeId").to("log:org.apache.camel.blog?groupSize=100");嘗試運行此程序。 您會發現您的消費者立即被封鎖,堆棧跟蹤將顯示出這種美麗:
"Camel (camel-1) thread #1 - JmsConsumer[test.queue]" daemon prio=5 tid=7f81eb4bc000 nid=0x10abbb000 in Object.wait() [10abba000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <7f40e9070> (a org.apache.commons.pool.impl.GenericKeyedObjectPool$Latch) at java.lang.Object.wait(Object.java:485) at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1151) - locked <7f40e9070> (a org.apache.commons.pool.impl.GenericKeyedObjectPool$Latch) at org.apache.activemq.pool.ConnectionPool.createSession(ConnectionPool.java:146) at org.apache.activemq.pool.PooledConnection.createSession(PooledConnection.java:173) at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196) ....怎么可能呢? 我們有連接池...我們將每個連接的會話數設置為每個連接10個,那么我們如何阻止創建新會話呢?
答案是,您正在耗盡會話數,就像堆棧跟蹤所期望的那樣。 但是如何? 我需要喝多少才能解決這個問題?
好吧,現在等等。 喝啤酒,聽我說。
首先了解一下。 ActiveMQ的池實現使用commons-pool ,而maxActiveSessionsPerConnection屬性實際上已映射到基礎池的maxActive屬性。 從文檔中這意味著:
maxActive controls the maximum number of objects (per key) that can allocated by the pool (checked out to client threads, or idle in the pool) at one time.這里的鍵是“鍵”(字面意思是……文檔中的“每個鍵”子句)。 因此,在ActiveMQ實現中,關鍵是一個對象,它表示1)是否事務處理模式,以及2)確認模式是() ,如此處所示 。 簡而言之,對于該連接上使用的每個密鑰,您最終都會獲得一個“ maxActive”會話。.因此,如果您有使用事務的客戶端,則不進行任何事務,client-ack,auto-ack,transacted-session, dups-okay,等等,您可以開始看到對于每個排列,您最終都將獲得“ maxActive”會話。 因此,如果將maxActiveSesssionsionsPerConnection設置為10,則最終可能會得到10 x 2 x 4 == 80個會話。 這是藏在你腦海中的東西。
這里的第二個關鍵是,當camel-jms組件設置使用者時,它最終會在并發消費者會話指定的所有使用者之間共享一個連接。 這是一個有趣的觀點,因為camel-jms使用了底層Spring框架的DefaultMessageListenerContainer,不幸的是,此限制來自該庫。 因此,如果您有15個并發使用者,那么他們將共享一個連接(即使是池化……它也會從池中獲取一個連接并保持它)。 因此,如果您有15個使用者,每個使用者共享一個連接,每個使用者共享一個事務處理模式,每個使用者共享一個ack模式,那么您最終將嘗試為該連接創建15個會話。 最后,您得到了上述結果。
因此,我避免這些情況的經驗法則是:
- 確切了解您的每個生產者和消費者正在做什么,他們的TX和ACK模式是什么
- 需要時,請始終調整最大會話參數(會話線程太多?我不知道..),但并發ConsumersConsumers + 1的值應至少為ATEST
- 如果生產者和消費者正在生產/消費相同的目的地,則將連接池拆分:一個消費者池,一個生產者池
 鄧諾(Dunno)該信息將非常有價值,但我想親自寫下來。 如果其他人覺得它有價值或有疑問,請在評論中讓我知道。 
翻譯自: https://www.javacodegeeks.com/2014/03/lessons-learned-activemq-apache-camel-and-connection-pooling.html
總結
以上是生活随笔為你收集整理的获得的经验:ActiveMQ,Apache Camel和连接池的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 将旧项目从Ant迁移到Maven的4个简
- 下一篇: 安卓微信协议分析笔记(安卓微信协议)
