ActiveMQ官网上是这么写的(戳此跳转到官网页面):
ActiveMQ uses the Java Service Wrapper to run the broker. To configure how the Java Service Wrapper starts up, you can edit the wrapper.conf located in the bin/win32, bin/linux, or bin/macosx depending on which system you are running it. For more information on the different properties of the Java Service Wrapper, refer to this page
wrapper是个将java打包成windows或者unix的服务的一个工具。它同时还为应用程序提供日记功能,灵活的配置,可靠的运行性能,按需求重新启动,简化应用程序的安装等。
当你下载MQ并解压之后,你会发现文件夹如下所示(下图中,上面为macox、linux版,下图为windows版)
修改内存可通过修改wrapper.conf文件中的如下命令。
注意此处是通过什么方式启动,就修改哪个文件夹的wrapper.conf啊!比如你是win64启动方式,就改win64文件夹下的.conf,并且你运行的时候也是用win64文件夹下的activemq.bat哈
# Initial Java Heap Size (in MB)
# 等同于xms
wrapper.java.initmemory=1024
# Maximum Java Heap Size (in MB)
# 等同于xmx
wrapper.java.maxmemory=1024
在研究的过程中,发现了一个很有意思的东西,在此赘述下。
在bin文件夹下的activemq(unix可执行文件)的源代码中,发现了一个备注
# System variables for this script, like ACTIVEMQ_OPTS and ACTIVEMQ_OPTS_MEMORY,
# can be configured in 'env' script located in this directory.
并且在activemq(unix可执行文件)中,也能看到代码为
if [ -z "$ACTIVEMQ_OPTS" ] ; then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi
然后编辑env文件(windows版没有该文件)其中有一段代码如下
if [ -z "$ACTIVEMQ_OPTS_MEMORY" ] ; then
ACTIVEMQ_OPTS_MEMORY="-Xms64M -Xmx1G"
fi
if [ -z "$ACTIVEMQ_OPTS" ] ; then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi
if [ -z "$ACTIVEMQ_OUT" ]; then
ACTIVEMQ_OUT="/dev/null"
fi
也就是说,在此处也可以进行配置,经过测试发现,如果会用bin目录下的activemq进行启动(当然此处window没法用这个启动),就会使用到这个内存修改参数。
如果此文件修改了,使用的bin/xxx/下的activemq,最终wrapper会覆盖掉这个文件夹下的参数;
如果此文件修改了,使用的bin下的activemq,最终使用的是env下的参数;
下图为使用单独文件夹下的activemq启动,如图所示
下图为使用bin目录下的activemq启动,如图所示
两者启动的形成的命令行如下(在macos上,其余系统未尝试)
java -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/apache-activemq-5.16.6/conf/login.config -Dcom.sun.management.jmxremote -Djava.awt.headless=true -Djava.io.tmpdir=/apache-activemq-5.16.6//tmp -Dactivemq.classpath=/apache-activemq-5.16.6//conf:/apache-activemq-5.16.6//../lib/: -Dactivemq.home=/apache-activemq-5.16.6/ -Dactivemq.base=/apache-activemq-5.16.6/ -Dactivemq.conf=/apache-activemq-5.16.6//conf -Dactivemq.data=/apache-activemq-5.16.6//data -jar //apache-activemq-5.16.6//bin/activemq.jar start
/apache-activemq-5.16.6/bin/macosx/wrapper /apache-activemq-5.16.6/bin/macosx/wrapper.conf wrapper.syslog.ident=ActiveMQ wrapper.pidfile=/apache-activemq-5.16.6/bin/macosx/./ActiveMQ.pid wrapper.daemonize=TRUE
/usr/bin/java -Dactivemq.home=../.. -Dactivemq.base=../.. -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStorePassword=password -Djavax.net.ssl.keyStore=../../conf/broker.ks -Djavax.net.ssl.trustStore=../../conf/broker.ts -Dcom.sun.management.jmxremote -Dorg.apache.activemq.UseDedicatedTaskRunner=false -Djava.util.logging.config.file=logging.properties -Dactivemq.conf=../../conf -Dactivemq.data=../../data -Djava.security.auth.login.config=../../conf/login.config -Xms1024m -Xmx1024m -Djava.library.path=../../bin/macosx/ -classpath ../../bin/wrapper.jar:../../bin/activemq.jar -Dwrapper.key=ZpwQ3RjSWlo75KaJ -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=87518 -Dwrapper.version=3.2.3 -Dwrapper.native_library=wrapper -Dwrapper.service=TRUE -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1 org.tanukisoftware.wrapper.WrapperSimpleApp org.apache.activemq.console.Main start
从启动命令能大概看出来,使用wrapper的方式启动,能覆盖到直接用unix执行命令启动
ActiveMQ服务器data目录下wrapper.log文件,默认产生的日志是不覆盖的,文件的大小逐渐增大。累加后会出现文件越来越大。所以建议此处进行优化。找到以下代码进行修改。如下面因为所示,一个是最大的文件大小,和最多的文件数量。
# Maximum size that the log file will be allowed to grow to before
# the log is rolled. Size is specified in bytes. The default value
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
wrapper.logfile.maxsize=20m
# Maximum number of rolled log files which will be allowed before old
# files are deleted. The default value of 0 implies no limit.
wrapper.logfile.maxfiles=100
默认的activemq.xml的原文件,详见最后的源文件,其相关内容的配置,详见“极其复杂的官网配置页面”
activemq在登录管理后台的时候,是会需要账号密码的。如果需要修改管理后台的登录账号密码,可以修改"conf/jetty-realm.properties/jetty-realm.properties"文件,文件内容如下:
# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user
修改形式为 “用户名: 密码, 角色”,此处角色是怎么配置的,比较复杂,可以见"conf/jetty-realm.properties/jetty.xml"
broker就相当于一个Activemq实例
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" useJmx="true">
...
broker>
消息通知指的是broker上的操作记录的跟踪和通知,可通过配置关闭
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" advisorySupport="false">
...
broker>
按照官网的解释,系统中不应该有离线的持久化订阅者,这样会浪费众多资源。详见官网
所以建议配置以下参数
在对应的entry上增加expireMessagesPeriod配置,比如:
<policyEntry topic=">" expireMessagesPeriod="300000"/>
在broker的数据上增加以下参数
参数 | 默认 | 中文描述 | 英文描述 |
---|---|---|---|
offlineDurableSubscriberTimeout | -1 | 删除多久不活跃的订阅者(单位毫秒),如果配置为-1,则不删除 | Amount of time (in milliseconds) after which we remove inactive durable subs. Default -1, means don’t remove them |
offlineDurableSubscriberTaskSchedule | 300000 | 检查的频率(单位毫秒) | How often we check (in milliseconds) |
示例:
<broker name="localhost" offlineDurableSubscriberTimeout="86400000" offlineDurableSubscriberTaskSchedule="3600000">
.....
broker>
详见官网
参数名称 | 描述 | 配置数据 |
---|---|---|
schedulePeriodForDestinationPurge | 检查非活跃状态的queue间隔 | 3600000 |
gcInactiveDestinations | 声明该队列是否要被扫描到,默认是false | |
inactiveTimeoutBeforeGC | 声明该队列闲置多少秒被删除,默认60秒 |
其中上面的闲置,代表“无入队记录及无有效订阅”
示例
<broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="30000"/>
policyEntries>
policyMap>
destinationPolicy>
broker>
一个ActiveMQ,不能无认证授权的暴漏在外网中,如果这样,会出现信息泄露的风险。所以需要对ActiveMQ的broker进行认证授权配置,这样系统在连接MQ的时候,就必须配置账号密码,提高mq的安全。
在中,找到标签,在标签前增加以下插件配置:
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="账号" password="密码" groups="组别"/>
users>
simpleAuthenticationPlugin>
plugins>
此处账号密码可以写死,也可以通过加载配置文件引入,常用的配置方式是使用activemq.xml里面默认引入的配置文件“credentials.properties”,然后使用里面的配置的用户名和密码
比如:
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/>
<authenticationUser username="guest" password="${guest.password}" groups="guests"/>
users>
simpleAuthenticationPlugin>
plugins>
其中“credentials.properties”引入方式是通过(activemq.xml里面是默认使用的):
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.propertiesvalue>
property>
bean>
里面的内容是:
# Defines credentials that will be used by components (like web console) to access the broker
activemq.username=system
activemq.password=manager
guest.password=password
此处是以springboot为例,代码中需要配置
spring:
activemq:
broker-url: tcp://127.0.0.1:61616
user: system
password: manager
具体内容详见官网页面,未仔细研究,大概就是使用credentials_enc.properties的内容,密码形如“ENC(Cf3Jf3tM+UrSOoaKU50od5CuBa8rxjoL)”,如需要可以查看官网
在broker中使用TimeStampPlugin插件,此为一个时间戳插件,官网解释为:TimeStampPlugin插件
参数 | 默认 | 描述 | 英文描述 |
---|---|---|---|
futureOnly | false | When the plugin will never set a message’s time stamp and expiration time to a value lower than the original values. When the plugin always update a message’s time stamp and expiration time.truefalse | |
ttlCeiling | 0 | 表示过期时间上限(程序写的过期时间不能超过此时间,超过则以此时间为准) | When not zero, this value (in ms) limit the expiration time. |
zeroExpirationOverride | 0 | 表示过期时间(给未分配过期时间的消息分配过期时间) | When not zero this value (in ms) will override the expiration time for messages that do not have an expiration already set. |
也就是统一设置过期时间的上线和默认过期时间
<plugins>
<timeStampingBrokerPlugin ttlCeiling="1800000" zeroExpirationOverride="1800000" />
plugins>
消息过期后会进入死信队列,如不想抛弃死信队列,默认进入ACTIVEMQ.DLQ队列,且不会自动清除;对于过期的消息进入死信队列还有一些可选的策略:放入各自的死信通道、保存在一个共享的队列(默认),且可以设置是否将过期消息放入队列的开关以及死信队列消息过期时间。
使用discardingDLQBrokerPlugin插件,官网解释为:DiscardingDLQBrokerPlugin插件,按照自己的需求,配置一下内容即可
<plugins>
plugins>
activemq默认的持久化方式为kahaDB,当然如果有特殊需求,还可以配置jdbc作为持久化源。
所有参数,详见官网
默认的kahaDB的配置,只有存储路径
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
persistenceAdapter>
可以增加以下配置
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="32mb">
kahaDB>
persistenceAdapter>
注意,此处标签有两层,不是我多写了哈
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
tempUsage>
systemUsage>
systemUsage>
在log4j.properties中,增加以下参数,便可以输出kahadb的相关日志
### 测试kahadb,增加日志
log4j.appender.kahadb=org.apache.log4j.RollingFileAppender
log4j.appender.kahadb.file=${activemq.base}/data/kahadb.log
log4j.appender.kahadb.maxFileSize=1024KB
log4j.appender.kahadb.maxBackupIndex=5
log4j.appender.kahadb.append=true
log4j.appender.kahadb.layout=org.apache.log4j.PatternLayout
log4j.appender.kahadb.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
log4j.logger.org.apache.activemq.store.kahadb.MessageDatabase=TRACE, kahadb
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.propertiesvalue>
property>
bean>
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
bean>
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" start="false" restartAllowed="false"
schedulePeriodForDestinationPurge="3600000"
useJmx="true" advisorySupport="false" offlineDurableSubscriberTimeout="12000" offlineDurableSubscriberTaskSchedule="6000" deleteAllMessagesOnStartup="true">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" expireMessagesPeriod="60000">
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
pendingMessageLimitStrategy>
policyEntry>
<policyEntry queue=">"
gcInactiveDestinations="true" inactiveTimoutBeforeGC="21600000"
strictOrderDispatch="true" expireMessagesPeriod="60000">
policyEntry>
policyEntries>
policyMap>
destinationPolicy>
<managementContext>
<managementContext createConnector="false"/>
managementContext>
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb" lockKeepAlivePeriod="2000" ignoreMissingJournalfiles="true" enableAckCompaction = "true" journalMaxFileLength="32mb">
<locker>
<shared-file-locker lockAcquireSleepInterval="10000" />
locker>
kahaDB>
persistenceAdapter>
<plugins>
<timeStampingBrokerPlugin ttlCeiling="1800000" zeroExpirationOverride="1800000" />
<discardingDLQBrokerPlugin dropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />
plugins>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
tempUsage>
systemUsage>
systemUsage>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
transportConnectors>
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
shutdownHooks>
broker>
<import resource="jetty.xml"/>
beans>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.propertiesvalue>
property>
bean>
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
bean>
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" >
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
pendingMessageLimitStrategy>
policyEntry>
policyEntries>
policyMap>
destinationPolicy>
<managementContext>
<managementContext createConnector="false"/>
managementContext>
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
tempUsage>
systemUsage>
systemUsage>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
transportConnectors>
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
shutdownHooks>
broker>
<import resource="jetty.xml"/>
beans>
天行健,君子以自强不息;地势坤,君子以厚德载物