高并发
程序员文章站
2022-04-30 23:09:38
...
[b]垂直扩展[/b]
垂直扩展是一种用于增加单个ActiveMQ代理连接数(因而也增加了负载能力)的技术.默认情况下,
ActiveMQ的被设计成尽可高效的传输消息以确保低延迟和良好的性能.
默认情况下,ActiveMQ使用阻塞IO来处理传输连接,这种方式为每一个连接分配一个线程.
你可以为ActiveMQ代理使用非阻塞IO(同时客户端可以使用默认的传输)以减少线程的使用.
可以在ActiveMQ的配置文件中通过传输连接器配置非阻塞IO.下面的是配置非阻塞IO的示例
代码:
除了为每个连接使用一个线程的阻塞IO,ActiveMQ还可以为每一个客户端连接使用一个消息分发
线程.你可以通过将系统参数org.apache.activemq.UseDedicatedTaskRunner设置为false来设置
ActiveMQ使用一个搞线程池.下面是一个示例:
ACTIVEMQ_OPTS="-Dorg.apache.activemq.UseDedicatedTaskRunner=false"
确保ActiveMQ代理用于足够的内存来处理大量的并发连接,需要分两步进行:
首先,你需要确保运行ActiveMQ的JVM在启动之前已经配置了足够的内存.可以使用JVM的-Xmx选项来
配置,如下所示:
ACTIVEMQ_OPTS="-Xmx1024M -Dorg.apache.activemq.UseDedicatedTaskRunner=false"
其次,需要确保JVM配置了适量的专门供ActiveMQ代理使用的内存.这个配置可用通过<system-Usage> 元素的limit属性来配置.一个不错的根据经验得到的规则时,在连接数为几百个时配置512MB为最小内存.
broker配置中的系统内存和磁盘空间使用量
同样,简易减少每个连接的CPU负载.如果你正使用Open-Wire格式的消息,关闭tight encoding选项,
开启该选项会导致CPU占有过多.Tight encoding选项可以通过客户端连接的URI中的参数设置以便关闭
该选项.下
String uri = "failover://(tcp://localhost:61616?" + wireFormat.tightEncodingEnabled=false)";
ConnectionFactory cf = new ActiveMQConnectionFactory(uri);
默认的消息队列配置中使用一个独立的线程负责将消息存储中的消息提取到消息队列中而后再被
分发到对其感兴趣的消息消费者.如果有大量的消息队列,建议通过启用optimizeDispatch这个属性
改善这个特性,示例代码如下所示:
代码清单中使用通配符>表示该配置会递归的应用到所有的消息队列中.
为确保扩展配置既可以处理大量连接也可以处理海量消息队列,请使用JDBC或更新更快的KahaDB消息存储.默认情况下ActiveMQ使用KahaDB消息存储.
调优后的示例
[b]横向扩展[/b]
使用代理网络来增加应用程序可用的代理数量.因为网络会自动传递
消息给所有互联的具有对消息感兴趣的消息消费者的代理,所以你可以配置客户端连接到一个代理
集群,随机的选择集群中的一个代理来连接.可以通过URI中的参数来配置,如下所示:
failover://(tcp://broker1:61616,tcp://broker2:61616)?randomize=true
为了确保队列或持久化主题中的消息不会卡在某个代理上而不能进行转发,需要在配置网络连接时,将
dynamicOnly配置成true并使用小一点的prefetchSize.预读取数量
<networkConnector uri="static://(tcp://remotehost:61617)" name="bridge" dynamicOnly="true" prefetchSize="1"
</networkConnector>
另外一种可选的部署方案可以提供更多的扩展性和更好的性能,但是需要在应用程序中做更多的计划.
这种混合的解决方案被称为传输负载分流(traffic partitioning),这种方案通过在应用程序中分割消息目的地
到不同的代理上以完成垂直扩展.
客户端的传输负载分流是一个垂直和水平混合的负载分流方案.通常不使用代理网络,因为客户端程序
会决定将哪个负载发送到哪个(些)代理上.客户端程序需要维护多个JMS连接并且决定哪个JMS连接
应该用于那个消息目的地.
没有直接使用网络连接的好处是降低了代理见过量的消息转发.你不需要像在传统程序中那样进行
额外的负载的均衡处理.
[img]http://dl2.iteye.com/upload/attachment/0103/4158/401dfb62-5efd-364d-acb9-5be6fc69a40a.png[/img]
垂直扩展是一种用于增加单个ActiveMQ代理连接数(因而也增加了负载能力)的技术.默认情况下,
ActiveMQ的被设计成尽可高效的传输消息以确保低延迟和良好的性能.
默认情况下,ActiveMQ使用阻塞IO来处理传输连接,这种方式为每一个连接分配一个线程.
你可以为ActiveMQ代理使用非阻塞IO(同时客户端可以使用默认的传输)以减少线程的使用.
可以在ActiveMQ的配置文件中通过传输连接器配置非阻塞IO.下面的是配置非阻塞IO的示例
代码:
<broker>
<transportConnectors>
<!--nio模式-->
<transportConnector name="nio" uri="nio://localhost:61616"/>
</<transportConnectors>
</broker>
除了为每个连接使用一个线程的阻塞IO,ActiveMQ还可以为每一个客户端连接使用一个消息分发
线程.你可以通过将系统参数org.apache.activemq.UseDedicatedTaskRunner设置为false来设置
ActiveMQ使用一个搞线程池.下面是一个示例:
ACTIVEMQ_OPTS="-Dorg.apache.activemq.UseDedicatedTaskRunner=false"
确保ActiveMQ代理用于足够的内存来处理大量的并发连接,需要分两步进行:
首先,你需要确保运行ActiveMQ的JVM在启动之前已经配置了足够的内存.可以使用JVM的-Xmx选项来
配置,如下所示:
ACTIVEMQ_OPTS="-Xmx1024M -Dorg.apache.activemq.UseDedicatedTaskRunner=false"
其次,需要确保JVM配置了适量的专门供ActiveMQ代理使用的内存.这个配置可用通过<system-Usage> 元素的limit属性来配置.一个不错的根据经验得到的规则时,在连接数为几百个时配置512MB为最小内存.
broker配置中的系统内存和磁盘空间使用量
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage limit="512 mb"/>
</memoryUsage>
<storeUsage>
<storeUsage limit="10 gb" name="foo"/>
</storeUsage>
<tempUsage>
<tempUsage limit="1 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
同样,简易减少每个连接的CPU负载.如果你正使用Open-Wire格式的消息,关闭tight encoding选项,
开启该选项会导致CPU占有过多.Tight encoding选项可以通过客户端连接的URI中的参数设置以便关闭
该选项.下
String uri = "failover://(tcp://localhost:61616?" + wireFormat.tightEncodingEnabled=false)";
ConnectionFactory cf = new ActiveMQConnectionFactory(uri);
默认的消息队列配置中使用一个独立的线程负责将消息存储中的消息提取到消息队列中而后再被
分发到对其感兴趣的消息消费者.如果有大量的消息队列,建议通过启用optimizeDispatch这个属性
改善这个特性,示例代码如下所示:
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" optimizedDispatch="true"/>
</policyEntries>
</policyMap>
</destinationPolicy>
代码清单中使用通配符>表示该配置会递归的应用到所有的消息队列中.
为确保扩展配置既可以处理大量连接也可以处理海量消息队列,请使用JDBC或更新更快的KahaDB消息存储.默认情况下ActiveMQ使用KahaDB消息存储.
调优后的示例
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="amq-broker" dataDirectory="${activemq.base}/data">
<persistenceAdapter>
<kahaDB directory="${activemq.base}/data" journalMaxFileLength="32mb"/>
</persistenceAdapter>
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" optimizedDispatch="true"/>
</policyEntries>
</policyMap>
</destinationPolicy>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage limit="512 mb"/>
</memoryUsage>
<storeUsage>
<storeUsage limit="10 gb" name="foo"/>
</storeUsage>
<tempUsage>
<tempUsage limit="1 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<transportConnectors>
<transportConnector name="openwire" uri="nio://localhost:61616"/> </transportConnectors>
</broker>
[b]横向扩展[/b]
使用代理网络来增加应用程序可用的代理数量.因为网络会自动传递
消息给所有互联的具有对消息感兴趣的消息消费者的代理,所以你可以配置客户端连接到一个代理
集群,随机的选择集群中的一个代理来连接.可以通过URI中的参数来配置,如下所示:
failover://(tcp://broker1:61616,tcp://broker2:61616)?randomize=true
为了确保队列或持久化主题中的消息不会卡在某个代理上而不能进行转发,需要在配置网络连接时,将
dynamicOnly配置成true并使用小一点的prefetchSize.预读取数量
<networkConnector uri="static://(tcp://remotehost:61617)" name="bridge" dynamicOnly="true" prefetchSize="1"
</networkConnector>
另外一种可选的部署方案可以提供更多的扩展性和更好的性能,但是需要在应用程序中做更多的计划.
这种混合的解决方案被称为传输负载分流(traffic partitioning),这种方案通过在应用程序中分割消息目的地
到不同的代理上以完成垂直扩展.
客户端的传输负载分流是一个垂直和水平混合的负载分流方案.通常不使用代理网络,因为客户端程序
会决定将哪个负载发送到哪个(些)代理上.客户端程序需要维护多个JMS连接并且决定哪个JMS连接
应该用于那个消息目的地.
没有直接使用网络连接的好处是降低了代理见过量的消息转发.你不需要像在传统程序中那样进行
额外的负载的均衡处理.
[img]http://dl2.iteye.com/upload/attachment/0103/4158/401dfb62-5efd-364d-acb9-5be6fc69a40a.png[/img]