ActiveMQ Part 2 : 优化配置
这里所谓的优化,是基于使用 mqtt 协议和 topic 订阅发布模式为案例展开,尽量简化到最少资源开销;
1. 启动连接参数
打开 \conf\activemq.xml 配置文件,对 transportConnectors 节点进行配置,如下:
1 <transportConnectors> 2 <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> 3 <!-- <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>--> 4 <!-- <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>--> 5 <!-- <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>--> 6 <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600&transport.defaultKeepAlive=90000&allowLinkStealing=false&transport.activeMQSubscriptionPrefetch=1000&wireFormat.maxInactivityDuration=30000&wireFormat.maxInactivityDurationInitalDelay=10000&transport.useInactivityMonitor=true&transport.useKeepAlive=true"/> 7 <!-- <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>--> 8 </transportConnectors>
maximumConnections=1000&wireFormat.maxFrameSize=104857600 : 为了防止 DOS 攻击,限制了并发连接数及最大并发传输容量(最大容量: 256MB);
transport.defaultKeepAlive=90000 : 配置服务器的默认心跳;默认值为:假设客户端心跳时间为 10秒,服务端对该连接的检测时间则为:10*1.5=15秒;
此处配置为 90秒,则客户端心跳建议为:60秒(配置看场景需求而定);
allowLinkStealing=false : 如果有两个或以上的连接使用了相同的 CilentID,则视为盗链;服务器将丢弃后来者的连接(从日志可以看到以下信息)
WARN | Stealing link for clientId PUBSameID-001 From Connection
transport.activeMQSubscriptionPrefetch=100: 如果订阅端的处理能力较强,消息较小; 这个值越大越好,即服务端将预推多少消息量给订阅端,然后等订阅端 ACK后再推;
这个设置需要评估订阅端的最低处理能力,并根据服务器性能来配置;
wireFormat.maxInactivityDuration=90000: 如果服务器在 90s 内没有接收到某个连接发来的消息,则自动断开该连接;
transport.useKeepAlive=true: 如果设置为 false,则服务器在心跳时间外没收到数据也不会强制关闭连接;
wireFormat.maxInactivityDurationInitalDelay=10000: 指定 "不活动链接监视器 (InactivityMonitor)" 在服务启动后多长时间后启动,在需要并发创建许多连接场景非常能有效的降低服务器开销;
transport.useInactivityMonitor=true: 启用”不活动链接监视器“,如果设置为 false,则服务器不监控”不活动连接“;
2. 预存消息量
这里还需要关注 constantPendingMessageLimitStrategy 配置,与 Prefetch Size 相关;
慢消费者会在非持久的topics上导致问题:一旦消息积压起来,会导致broker把大量消息保存在内存中,broker也会因此而变慢。
可以通过配置缓存消息的上限,超过这个上限后,新消息到来时会丢弃旧消息;
如下配置,或者 使用倍数方式代替消息条数:<prefetchRatePendingMessageLimitStrategy multiplier="2.5"/>
1 <destinationPolicy> 2 <policyMap> 3 <policyEntries> 4 <policyEntry topic=">" > 5 <pendingMessageLimitStrategy> 6 <constantPendingMessageLimitStrategy limit="1000"/> 7 </pendingMessageLimitStrategy> 8 </policyEntry> 9 </policyEntries> 10 </policyMap> 11 </destinationPolicy>
3. 数据清理
A)消息主题 / 队列清理:在规定的时间内,如果无有效订阅,没有入队消息,超时后就会被清理;
配置包含以下三个值;
schedulePeriodForDestinationPurge : 在 broker 上设置任务清理周期(毫秒);
gcInactiveDestinations : 在策略上配置是否启用Topic(或queue)清理任务;
inactiveTimoutBeforeGC :Topic(queue)清理间隔周期(毫秒)
1 <broker schedulePeriodForDestinationPurge="86400000"> 2 <destinationPolicy> 3 <policyMap> 4 <policyEntries> 5 <policyEntry topic=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="43200000" ></policyEntry> 6 <policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="43200000" ></policyEntry> 7 </policyEntries> 8 </policyMap> 9 </destinationPolicy> 10 </broker>
4. 内存与磁盘空间
对 ActiveMQ 的使用空间策略配置;
memoryUsage :ActiveMQ使用的内存(可用的百分比),必须大于或等于 destinationPolicy 中设置的所有队列的内存之和;
storeUsage :持久化存储文件的大小;
tempUsage :非持久化消息存储的临时内存大小;
1 <broker> 2 <systemUsage> 3 <systemUsage> 4 <memoryUsage> 5 <memoryUsage percentOfJvmHeap="70" /> 6 </memoryUsage> 7 <storeUsage> 8 <storeUsage limit="100 gb"/> 9 </storeUsage> 10 <tempUsage> 11 <tempUsage limit="50 gb"/> 12 </tempUsage> 13 </systemUsage> 14 </systemUsage> 15 </broker>