1.加载credentials.properties文
file:${activemq.conf}/credentials.properties
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
# Defines credentials that will be used by components (like web console) to access the broker
activemq.username=system
activemq.password=manager
guest.password=password
启动脚本:activemq的内存大小来自环境变量
# Set jvm memory configuration
if [ -z "$ACTIVEMQ_OPTS_MEMORY" ] ; then
ACTIVEMQ_OPTS_MEMORY="-Xms1G -Xmx1G"
fi
2、broker策略配置:
3、流控制
如果是嵌入式(embedded)方式使用的话,可以new一个SystemUsage来添加到BrokerService中去。这里配置的memoryUsage一定要小于jvm中设置的数量。
5.9.0后版本,如果设置的 memoryUsagelimit大于实际可用java heap size值,比如默认启动 xmx=1G,那么实际的java heap size大概是910M,
则broker启动时会log.error提示设置内存出错,然后强制使用实际java heap size* 70% = 637M作为memoryUsagelimit。
splitSystemUsageForProducersConsumers导致消费缓慢甚至无法消费的问题
其实broker中还可以单独配置生产者使用的producerSystemUsage 和消费者使用的consumerSystemUsage,格式跟systeUsage一样。
默认情况下,没有配置producerSystemUsage 和 consumerSystemUsage,则生产者和消费者都使用systemUsage。
这时可能会因为生产者线程把内存用完,导致消费者线程处理缓慢甚至无法消费的问题。这种情况下,添加消费端的机器和消费者数量可能都无法增加消费的速度。
解决办法就是:
在broker上设置splitSystemUsageForProducersConsumers=”true”,使得生产者线程和消费者线程各使用各的内存。
默认是 生产者线程内存:消费者线程内存 = 6:4。
也可以通过如下两个参数设置生产者线程内存和消费者线程内存各一半:
producerSystemUsagePortion = 50
consumerSystemUsagePortion = 50
生产者流控
从5.x版本起,可以给每个producer单独设置流控。流控简单的说就是控制生产者的在内存使用限制下的行为。当然,流控的目的在于防止在将ActiveMQ作为内存MQ使用时,生产速度大于消费速度时将MQ撑爆的问题。
分两个情况:
1、 同步发送消息(useAsynSend为false):此时将在SystemUsage的限制下,使用destinationPolicy中的policyEntry中的限制,例如:
限制非持久化时queueA 的内存使用量为1mb,达到这个内存使用量时直接阻塞掉producer,直到有空余的内存时,才允许producer发送消息。
也可通过在systemUsage配置上设置sendFailIfNoSpace="true"或 sendFailIfNoSpaceAfterTimeout="3000"来控制客户端异常和等待时间。
异步发送时,由于不阻塞生产者,
可以通过connctionFactory.setProducerWindowSize(1024000);
来控制broker确认收到消息前生产者能发送的最大数据量(字节)。
消费者流控
消费者端,一般来说消费的越快越好,broker的积压越小越好。
但是考虑到事务性和客户端确认的情况,如果一个消费者一次获取到了很多消息却都不确认,这会造成事务上下文变大,broker端这种“半消费状态”的数据变多,所以ActiveMQ有一个prefetchSize参数来控制未确认情况下,最多可以预获取多少条记录。
默认情况如下:
持久化queue:1000条
非持久化queue: 1000条
持久化topic:100条
非持久化topic: 无限制
可以通过3中方式设置prefetchSize
1、 tcp://localhost:61616?jms.prefetchPolicy.all=50
2、 tcp://localhost:61616?jms.prefetchPolicy.queuePrefetch=1
3、 queue = new ActiveMQQueue("TEST.QUEUE?consumer.prefetchSize=10");
----------------------------------------------------------------------------------------------------------------------------------
4、协议
可以看到在
INFO TransportServerThreadSupport - Listening for connections at:
tcp://localhost:61616
INFO TransportConnector - Connector openwire Started
INFO TransportServerThreadSupport - Listening for connections at:
ssl://localhost:61617
INFO TransportConnector - Connector ssl Started
INFO TransportServerThreadSupport - Listening for connections at:
stomp://localhost:61613
INFO TransportConnector - Connector stomp Started
INFO TransportServerThreadSupport - Listening for connections at:
xmpp://localhost:61222
INFO TransportConnector - Connector xmpp Started
去掉非必需的通信协议(Client与Broker、Broker与Broker之间使用该协议进行通信),只留下TCP协议(特别需要注意的是61616是broker的监听端口):
从客户端的角度来看,transportConnector的URI是用于和broker建立连接,以通过该连接来发送和接受消息。例如,以下Java代码通过之前配置文件中定义的”openwire“那个transportConnector来与broker建立连接:
ActiveMQConnectionFactory factory =
new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
connection.start();
Session session =
connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Transport Connector的可用协议