title: 部署activemq单节点 #标题tags: mq #标签
date: 2020-10-25
categories: MQ # 分类
Activemq知识点
服务器挂掉会不会丢数据
这得从ActiveMQ的储存机制说起。在通常的情况下,非持久化消息是存储在内存中的,持久化消息是存储在文件中的,它们的最大限制在配置文件的节点中配置。但是,在非持久化消息堆积到一定程度,内存告急的时候,ActiveMQ会将内存中的非持久化消息写入临时文件中,以腾出内存。虽然都保存到了文件里,但它和持久化消息的区别是,重启后持久化消息会从文件中恢复,非持久化的临时文件会直接删除。
文件增大到配置中的最大限制会怎样
第一个问题说到,持久化消息是存储在文件中的,它们的最大限制在配置文件的节点中配置,那如果文件超过了这个大小,对于持久化文件限制来说,大量生产持久化消息直到文件达到最大限制,此时生产者阻塞,但消费者可正常连接并消费消息,等消息消费掉一部分,文件删除又腾出空间之后,生产者又可继续发送消息,服务自动恢复正常。对于非持久化文件限制来说,大量生产非持久化消息并写入临时文件,在达到最大限制时,生产者阻塞,消费者可正常连接但不能消费消息,或者原本慢速消费的消费者,消费突然停止。整个系统可连接,但是无法提供服务,就这样挂了。
建议:尽量不要用非持久化消息,非要用的话,将临时文件限制尽可能的调大。
部署ActiveMQ 5.16
配置jdk环境
自行去oracle官网下载java包,然后上传至各个服务器。
# 配置jdk环境(jdk版本不可过高,已验证jdk 14会在activemq启动后无法连接到zookeeper)
# 当然,如果你只是按照此文章部署个单节点,并不连接zookeeper,那没关系
$ tar zxf jdk-8u261-linux-x64.tar.gz -C /opt/
$ ln -sf /opt/jdk1.8.0_261 /opt/jdk
$ cat >> /etc/profile << EOF
export JAVA_HOME=/opt/jdk
export CLASSPATH=\$JAVA_HOME/lib
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
$ source /etc/profile
$ $ java -version # 查看版本信息
java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)
部署Activemq
# 下载及解压
$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/activemq/5.16.0/apache-activemq-5.16.0-bin.tar.gz
$ tar zxf apache-activemq-5.16.0-bin.tar.gz -C /opt/
$ ln -sf /opt/apache-activemq-5.16.0 /opt/activemq
$ cd /opt/activemq/
########### 配置与优化 ###########
# 修改active启动内存
$ vim /opt/activemq/bin/env
ACTIVEMQ_OPTS_MEMORY="-Xms64M -Xmx1G" # 找到此行
# 改为如下,建议Xms和Xmx值为一致,并且是系统内存的一半
ACTIVEMQ_OPTS_MEMORY="-Xms2G -Xmx2G"
# 修改配置文件
$ vim /opt/activemq/conf/activemq.xml
# 找到(40行左右)
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
# 改为
<broker xmlns="http://activemq.apache.org/schema/core" useJmx="true" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
# 找到(大概56、57行)
</pendingMessageLimitStrategy>
</policyEntry>
# 在57行 </policyEntry>字段下面增加一行
<policyEntry queue=">" prioritizedMessages="true" />
# 找到(71、72、73行)
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
# 改为
<managementContext>
<managementContext createConnector="true" connectorPort="11099"/>
</managementContext>
# 找到(91行左右),以下是定义存储文件最大限制,一般可能需要更改storeUsage中的值
# tempUsaage是调整非持久文件限制
# memoryUsage是调整内存使用限制,默认是java虚拟机可用内存的70%
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
# 找到(大概112行左右)
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<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>
# 注释掉除tcp以外的行,修改为:
<transportConnector name="auto+nio" uri="auto+nio://0.0.0.0:61608?maximumConnections=1000&wireFormat.maxFrameSize=524288000&org.apache.activemq.transport.nio.SelectorManager.corePoolSize=20&org.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=50" />
# 从这里开始注释 <!-- <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>
# 修改WEB管理页面监听地址及端口
$ vim /opt/activemq/conf/jetty.xml
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/> # 监听地址
<property name="port" value="8161"/> # 监听端口
</bean>
$ vim /opt/activemq/conf/jetty-realm.properties # 修改管理台用户免密
admin: 123.com, admin
# 注意:用户名和密码的格式是 用户名:密码:角色名。
Activemq网络优化参考
ActiveMQ在Version 5.13.0+ 版本后,将OpenWire, STOMP, AMQP, MQTT这四种主要协议的端口监听进行了合并,并使用auto关键字进行表示。也就是说,ActiveMQ将监听这一个端口的消息状态,并自动匹配合适的协议格式。配置如下:
<transportConnectors>
<transportConnector name="auto" uri="auto://0.0.0.0:61617?maximumConnections=1000" />
</transportConnectors>
以上的URI配置信息中,可以使用所有通用的Connection Configuration、Wire Formats Configuring、Server side options和TCP Transport Configuration配置项。但是这种优化只是让ActiveMQ的连接管理变得简洁了,并没有提升单个节点的处理性能。
如果不特别指定ActiveMQ的网络监听端口,那么这些端口都将使用BIO网络IO模型。所以为了提高单节点的网络吞吐性能,我们需要明确指定Active的网络IO模型,如下所示:
<transportConnectors>
<transportConnector name="nio" uri="nio://0.0.0.0:61618?maximumConnections=1000"/>
</transportConnectors>
请注意,URI格式头以nio开头,表示这个端口使用以TCP协议为基础的NIO网络IO模型。但是这样的设置方式,只能使这个端口支持Openwire协议。那么我们怎么既让这个端口支持NIO网络IO模型,又让它支持多个协议呢?ActiveMQ的服务端设置,允许开发人员使用+符号来为端口设置多种特性,如下:
// 表示这个端口使用NIO模型支持Stomp协议
<transportConnector name="stomp+nio" uri="stomp+nio://0.0.0.0:61613?transport.transformer=jms"/>
// 表示这个端口支持amqp和ssl密文传输
<transportConnector name="amqp+ssl" uri="amqp+ssl://localhost:5671"/>
所以如果我们既需要某一个端口支持NIO网络IO模型,又需要它支持多个协议,那么可以进行如下的配置:
<transportConnector name="auto+nio" uri="auto+nio://0.0.0.0:61608?maximumConnections=1000" />
另外,如果是为了生产环境进行的配置,那么至少应该还要配置这个端口支持的最大连接数量、设置每一条消息的最大传输值、设置NIO使用的线程池最大工作线程数量:
<transportConnector name="auto+nio" uri="auto+nio://0.0.0.0:61608?maximumConnections=1000&wireFormat.maxFrameSize=524288000&org.apache.activemq.transport.nio.SelectorManager.corePoolSize=20&org.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=50" />
# maximumConnections:最大客户端连接数
# maxFrameSize:单个消息最大字节数
# corePoolSize/maximumPoolSize:额外设置NIO使用的线程池核心工作线程数和最大工作线程数
启动Activemq
$ /opt/activemq/bin/activemq start
$ ss -lnput | grep java # activemq默认监听端口如下
tcp LISTEN 0 50 [::]:37103 [::]:* users:(("java",pid=16901,fd=8))
tcp LISTEN 0 128 [::]:61616 [::]:* users:(("java",pid=16901,fd=136))
tcp LISTEN 0 50 [::]:11099 [::]:* users:(("java",pid=16901,fd=118))
tcp LISTEN 0 50 [::]:8161 [::]:* users:(("java",pid=16901,fd=137))
# 61616:客户端连接端口
# 8161 : activemq的web管理平台端口号
# 11099: jmx监控activemq端口
访问web管理台
访问activemq的8161端口,看到如下页面,输入用户名和密码,我在上述配置文件中将admin的密码配置为了123.com
。
至此,单节点部署完成,可以交给开发小伙伴使用了。