2018.11.25更新
現(xiàn)在回頭看看這篇文章仔雷,其實是有問題的「鸨蹋看看閱讀量已經(jīng)到了3000借杰,感覺還是需要更正一下。
ActiveMQ的傳統(tǒng)配置使用的BIO模式进泼,也是Blocking IO模式蔗衡,在這種模式下,ActiveMQ的每一個客戶端所建立的連接乳绕,需要使用一個線程來承載绞惦,JVM的默認配置里Xss=1024,也就是每個線程需要1MB堆外內(nèi)存洋措,這樣就導致了前期測試的時候發(fā)現(xiàn)堆外內(nèi)存會影響連接數(shù)济蝉。
在高并發(fā)的情況下,使用BIO模式是很危險的。在我們的環(huán)境中已經(jīng)出現(xiàn)了堆外內(nèi)存溢出的情況王滤。所以建議都使用NIO模式贺嫂,NIO模式里不再使用線程來承載連接,而是使用連接池來承載請求雁乡。特別是連接數(shù)量上千的時候第喳。
在AMQ的官網(wǎng)里有類似的描述
If you want to scale your broker to support thousands of connections to it, you need to first find the limits of number of threads JVM process is allowed to create. Then you can set these properties to some value below that (broker need more threads to operate normally). For more information on thread usage by destinations and how to limit those, please take a look at Scaling Queues or this configuration file. For example you can add the following
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS -Dorg.apache.activemq.transport.nio.SelectorManager.corePoolSize=2000 -Dorg.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=2000 -Dorg.apache.activemq.transport.nio.SelectorManager.workQueueCapacity=1024"
to the startup script (${ACTIVEMQ_HOME}/bin/env
for example) to have a constant pool of 2000 threads handling connections. With the setting like this, the broker should be able to accept the number of connections up to the system limits. Of course, accepting connections is just one part of the story, so there are other limits to vertically scaling the broker.
也就是首先需要調(diào)整為NIO模式,而后對NIO模式進行核心線程池踱稍、最大線程池容量和線程池隊列容量的配置墩弯。
原文
在項目前期對amq的測試過程中,我們摸索出一臺4C8G的amq可以支持的最大連接數(shù)約為6000個寞射。最近和其它的項目合作,他們進行了一次連接數(shù)的測試锌钮,得到9000個連接才會導致mq宕機的結(jié)果桥温。3000個連接的差異意味著我的測試中一定有什么不對。所以這兩天研究了一下mq的連接機制梁丘,也進行了幾次測試侵浸,現(xiàn)在需要總結(jié)一下。
2C4G的amq氛谜,env的配置里Jvm的配置我配置成了Xms4G Xmx6G掏觉。
嗯,基本上就是我一開始以為這臺機器是4C8G值漫,配錯了……
使用客戶端測試澳腹,連接池Poolconnection的方式,能支持的連接數(shù):
Xms4G Xmx6G:2823
Xms256m Xmx1G:8160
這里連接數(shù)的測試是測試到mq直接被壓垮為止杨何,也就是說在8160個連接的時候酱塔,Amq的日志顯示報錯并且amq進程停止。
也就是說jvm的內(nèi)存設(shè)置并不是越大越好的危虱。
接著測試了一下羊娃,6000個連接的時候,2C4G的amq仍然可以正常跑埃跷。
結(jié)論:AMQ的JVM堆內(nèi)存設(shè)置不是越大越好的蕊玷。
究其原因,每個往AMQ的連接弥雹,AMQ都會建立一個線程與之對應垃帅,而后定時發(fā)送心跳,因此連接數(shù)量其實就是單個進程能建立的線程數(shù)剪勿,每個線程建立時會使用jvm堆內(nèi)存外的內(nèi)存挺智,所以jvm內(nèi)存設(shè)置小,反而連接數(shù)多
百度了一下,相關(guān)說明
影響線程數(shù)量的因素有下面幾個:
- -Xms: intial java heap size
- -Xmx: maximum java heap size
- -Xss: the stack size for each thread
- 系統(tǒng)限制: 系統(tǒng)最大可開線程數(shù)
增大堆內(nèi)存(-Xms赦颇,-Xmx)會減少可創(chuàng)建的線程數(shù)量二鳄,增大線程棧內(nèi)存(-Xss,32位系統(tǒng)中此參數(shù)值最小為60K)也會減少可創(chuàng)建的線程數(shù)量媒怯。
系統(tǒng)限制:
/proc/sys/kernel/pid_max订讼,
/proc/sys/kernel/thread-max,
max_user_process(ulimit -u)扇苞,
/proc/sys/vm/max_map_count欺殿。