1. ActiveMQ 支持哪些协议?
- ActiveMQ 支持多种协议传输和传输方式,允许客户端使用多种协议连接。
- ActiveMQ 支持的协议:AUTO、OpenWire、AMQP、Stomp、MQTT 等。
- ActiveMQ 支持的基础传输方式:VM、TCP、SSL、UDP、Peer、Multicast、HTTP(S) 等,以及更高级的 Failover、Fanout、Discovery、ZeroConf 方式。
ActiveMQ 协议连接配置
- 在 ${ACTIVEMQ_HOME}/conf/activemq.xml 中,通过配置 <transportConnectors> 就可以使用多种传输方式。
<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>
2. 数据传输方式及配置
1. TCP
- 由于 TCP 具有可靠传输的特性,它在 ActiveMQ 中也是最常使用的一种协议。在默认的配置中,TCP 连接的端口为 61616。
- 配置格式
tcp://hostname:port?key=value
- 配置参数说明
- 在服务器端配置时,参数要以“transport.”开头。
tcp://localhost:61616?transport.threadName&transport.trace=false&transport.soTimeout=60000
- 在客户端连接时,参数省略“transport.”前缀。
tcp://localhost:61616?transport.threadName&trace=false&soTimeout=60000
- 配置参数说明
属性 | 默认值 | 描述 |
backlog | 5000 | 指定传输服务器套接字等待接受的最大连接数。 |
connectionTimeout | 30000 | 超时时间,>=1 时才有超时时间(单位为毫秒)。<br/>为 0 表示没有超时,负值被忽略。 |
daemon | false | 如果为 true,则传输线程将以守护进程模式运行。<br/>将代理嵌入 Spring 容器或 Web 容器中时,请将此参数设置为 true,以允许容器正确关闭。 |
dynamicManagement | false | 如果为 true,则可以通过 JMX 管理 TransportLogger。 |
ioBufferSize | 8*1024 | 协议解析使用的缓冲区的大小。(非 TCP 缓冲区) |
jmxPort | 1099 | (仅在客户端有效)JMX 端口。 |
keepAlive | false | 如果为 true,则在 Broker 连接上启用 TCP keepAlive,以防止连接在 TCP 级别超时。<br/>这不要和 InactivityMonitor 使用的 KeepAliveInfo 消息混淆。 |
maximumConnections | Integer.MAX_VAUE | broker 允许的最大 socket 数。 |
socketBufferSize | 64*1024 | 设置接受的套接字读取缓冲区的大小(以字节为单位) |
soLinger | Integer.MIN_VALUE | 当值 >-1 时,设置套接字的选项 soLinger;设置为 -1 时,将禁用soLinger 套接字选项。 |
soTimeout | 0 | 设置套接字的读取超时(以毫秒为单位);值 0 表示没有超时。 |
soWriteTimeout | 0 | 设置套接字的写入超时(以毫秒为单位);值 0 表示没有超时。 |
stackSize | 0 | 设置服务端后台读取线程的堆栈大小;<br/>必须以 128k 的倍数指定;值 0 标识忽略此参数。 |
startLogging | true | true,将传输信息 TransportLogger 对象写入日志。<br/>仅在 trace=true 的场景下生效。 |
tcpNoDelay | false | 如果为 true,则设置套接字的选项 TCP_NODELAY。<br/>这会禁用 Nagle 的小数据包传输算法。 |
threadName | N/A | 指定调用 transport 的线程名称。<br>如果以服务器 host 命名,调试线程的时候可以看到。 |
trace | false | 为 true 时,服务器记录传输发送的所有命令内容。<br/>log4j.logger.org.apache.activemq.transport.TransportLogger=Debug |
trafficClass | 0 | ip 协议级别的服务质量参数。(0x02,0x04,0x08,0x10) |
useInactivityMonitor | true | false,禁用 InactivityMonitor,连接永远不会超时。 |
useKeepAlive | true | true,在空闲连接上发送 KeepAliveInfo 消息,防止它超时。<br/>false,指定的时间内没有接收到数据,连接超时。 |
2. SSL
- 需要一个安全连接的时候可以考虑使用 SSL,适用于 client 和 broker 在公网的情况。如使用 aws 云平台等。
- 官方介绍(http://activemq.apache.org/ssl-transport-reference.html)
- SSL 配置格式,可配置参数与 TCP 相同。
ssl://localhost:61616
- SSL 客户端配置
- JMS 客户端需要使用 ActiveMQSslConnectionFactory 类创建连接,brokerUrl 以 ssl:// 开头,以下是 Spring 配置示例。
<bean id="AMQJMSConnectionFactory" class="org.apache.activemq.ActiveMQSslConnectionFactory">
<property name="trustStore" value="/path/to/truststore.ts"/>
<property name="trustStorePassword" value="password"/>
<property name="keyStore" value="/path/to/keystore.ks"/>
<property name="keyStoreKeyPassword" value="password"/>
<property name="brokerURL" value="ssl://localhost:61616"/>
<property name="userName" value="root"/>
<property name="password" value="admin"/>
</bean>
- SSL 主机名验证
- 从 ActiveMQ 5.15.6 开始,ActiveMQ 开始支持 TLS 主机名验证,默认情况下客户端启用了该验证,而服务器端没有启用。
- 服务器端配置
ssl://localhost:61616?transport.verifyHostName=true
- 客户端配置
ssl://localhost:61616?socket.verifyHostName=false
或者
ssl://localhost:61616?verifyHostName=false
3. NIO
- 使用 Java 的 NIO 方式对连接进行改进,因为 NIO 使用线程池,可以复用线程,所以可以用更少的线程维持更多的连接。如果有大量的客户端,或者性能瓶颈在网络上传输上,可以考虑使用 NIO 的连接方式。
- NIO 配置格式,可配置参数与 TCP 相同
nio://hostname:port?key=value
- NIO 是 OpenWire 协议的传输方式,其他协议,像 AMQP、MQTT、Stomp,也有 NIO 的实现,通常在协议前缀中加“+nio”来区分。
mqtt+nio://localhost:1883
- NIO 传输线程使用情况设置
- 从 5.15.0 开始,ActiveMQ 支持调整 NIO 的传输线程,可以设置以下属性。
属性 | 默认值 | 描述 |
org.apache.activemq.transport.nio.<br/>SelectorManager.corePoolSize | 10 | 核心线程池线程数 |
org.apache.activemq.transport.nio.<br/>SelectorManager.maximumPoolSize | 1024 | 线程池最大线程数 |
org.apache.activemq.transport.nio.<br/>SelectorManager.workQueueCapacity | 0 | 线程池队列容量 |
org.apache.activemq.transport.nio.<br/>SelectorManager.rejectWork | false | 当达到容量时,允许使用 IOException 拒绝工作,以便可以保留现有的 QOS |
- 属性在 ${ACTIVEMQ_HOME}/bin/env 中配置,示例:
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS -Dorg.apache.activemq.transport.nio.SelectorManager.corePoolSize=2000 -Dorg.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=2000 -Dorg.apache.activemq.transport.nio.SelectorManager.workQueueCapacity=1024"
- NIO SSL
- 从 ActiveMQ5.6 版本开始,NIO 可以支持和 SSL 搭配使用的传输连接。
- 配置格式,可配置参数和 TCP 相同
nio+ssl://0.0.0.0:61616
4. UDP
- 与面向连接,可靠的字节流服务的 TCP 不同,UDP 是一个面向数据的简单传输连接,没有 TCP 的三次握手,所以性能大大强于 TCP,但是是以牺牲可靠性为前提。适用于丢失也无所谓的消息。
- UDP 配置格式
udp://localhost:8123
- UDP 配置参数说明
属性 | 默认值 | 描述 |
trace | false | 为 true 时,将会记录传输发送的所有命令。 |
useLocalHost | true | 为 true 时,本机机器名解析为 localhost。 |
datagramSize | 4*1024 | 指定数据报的大小。 |
5. HTTP(S)
- 需要穿越防火墙,可以考虑使用 HTTP(S),但由于 HTTP(S) 是短连接,每次创建连接的成本较高,所以性能最差。通过 XML 传输数据。
- HTTP 配置格式
http://localhost:8080?param1=val1¶m2=val2
- HTTPS 配置格式
https://localhost:8080?param1=val1¶m2=val2
6. VM
- 虚拟机协议(方法直调),使用场景是 client 和 broker 在同一个 Java 虚拟机内嵌的情况,无需网络通信的开销。
- VM 配置格式:
vm://brokerName?marshal=false&broker.persistent=false
- VM 配置参数说明
属性 | 默认值 | 描述 |
create | true | 如果不存在,则创建 broker。 |
waitForStart | -1 | 如果 >0,则表示等待代理超时(以毫秒为单位)。值 -1 和 0 表示不等待。仅在 ActiveMQ5.2+ 支持。 |
wireFormat | default | 命令的组装格式(协议)。 |
marshal | false | 强制发送的每个命令使用 WireFormat 进行格式转换。 |
3. OpenWire 协议
1. OpenWire 协议是什么?
- OpenWire 是 Apache 的一种跨语言的协议,允许从不通的语言和平台访问 ActiveMQ,是 ActiveMQ 4.x 以后的版本默认的传输协议。
- http://activemq.apache.org/openwire-version-2-specification
- http://activemq.apache.org/wire-protocol.html
2. OpenWire 协议如何使用
- OpenWire 支持 TCP、SSL、NIO、UDP、VM 等传输方式,直接配置这些连接,就是使用的 OpenWire 协议,OpenWire 有自己的配置参数,客户端和服务器端配置的参数名都是通过前缀“WireFormat.”表示。
- http://activemq.apache.org/configuring-wire-formats.html
- 示例:
tcp://localhost:61616?wireFormat.cacheEnabled=false&wireFormat.tightEncodingEnabled=false
- 配置参数说明
属性 | 默认值 | 描述 |
stackTraceEnabled | true | 是否应该把已经发生并且跟踪到的堆栈异常,通过 broker 发送到客户端。 |
tcpNoDelayEnabled | true | socket 的 NoDelay 参数。 |
cacheEnabled | true | 是否应该缓存不断重复的值,以便减少编组(马上要进行的发送)。 |
tightEncodingEnabled | true | 根据 CPU 使用情况,自动调整传输内容大小(压缩比例)。 |
sizePrefixDisabled | false | 每个包封送前,每个包的大小是否应该作为前缀。 |
maxInactivityDuration | 30000 | 连接的最大空闲时间,以毫秒为单位。<br/>broker服务器会根据配置关闭超时的连接。<br/>同时也可以通过心跳机制来保持连接。<br/>值 <=0 则禁用活动连接的监测。 |
maxInactivityDurationInitalDelay | 10000 | 连接建立之后,多久开始进行超时检测。 |
cacheSize | 1024 | 如果能被缓存,那么这个规定了缓存的最大数量。此属性在 ActiveMQ 的 4.1 中开始添加使用。 |
maxFrameSize | MAX_LONG | 可发送最大帧大小。<br/>可以帮助防止 OOM DOS 攻击。 |
4. MQTT 协议
1. MQTT 协议是什么?
- MQTT(Message Queuing Telemetry Transport) 消息队列遥测传输是 IBM 开发的一个即时通讯协议,已成为物联网通信的标准。
2. 为什么使用 MQTT
- MQTT 的结构简单,相对于其他消息协议,它更加轻量级。适合在计算能力有限、低带宽、不可靠的网络环境使用。
3. MQTT 的发布订阅模型
4. MQTT 服务质量
- 什么是服务质量
- 服务质量(QoS)级别是一种关于发送者和接收者之间信息投递的保证协议。MQTT 中有三种 QoS 级别:
- 至多一次(0)
- 至少一次(1)
- 只有一次(2)
- 为什么要有服务质量
- QoS 是 MQTT 的一个主要功能,它使得在不可靠的网络下进行通信变得更为简单,因为即使在非常不可靠的网络下,协议也可以掌控是否需要重发消息并保证消息到达。它也能帮助客户端根据网络环境和程序逻辑来自由选择 QoS。
- 它是如何工作的
- QoS level 0
- Qos level 1
- 针对客户端发布消息到服务器的消息流。
- 针对服务器发布到订阅者的消息流。
- QoS level 2
- 针对客户端发布消息到服务器的消息流。
- 针对服务器发布到订阅者的消息流。
5. ActiveMQ 服务器端配置
<transportConnectors>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
- MQTT 配置参数说明
属性 | 默认值 | 描述 |
maxFrameSize | 268435456 | (v5.12.0)可以发送的最大帧大小。协议限制为 256M,其值不能设置得更高。可以帮助防止 OOM DOS 攻击。 |
- 配置示例
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?wireFormat.maxFrameSize=100000"/>
- MQTT 使用 NIO
<transportConnector name="mqtt+nio" uri="mqtt+nio://0.0.0.0:1883"/>
- MQTT 使用 NIO+SSL
<transportConnector name="mqtt+nio" uri="mqtt+nio+ssl://0.0.0.0:1883"/>
- MQTT 也支持层次结构和通配符,但分隔符与 ActiveMQ 不同,映射关系:
作用 | ActiveMQ | MQTT |
分隔符 | . | / |
元素 | * | + |
子节点 | > | # |
- 示例
主题名:foo.blah.bar
在 MQTT 的客户端订阅时,可以为 foo/+/bar
在 JMS 订阅时,可以为 foo.*.bar
6. Spring 使用 MQTT
- Spring Integration 提供了 MQTT 协议的支持,通过 Maven 添加依赖即可使用。
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
- https://docs.spring.io/spring-integration/reference/html/mqtt.html
5. AUTO 协议
1. AUTO 协议是什么
- Auto 自动检测协议。
- 从 ActiveMQ 5.13.0 开始,ActiveMQ 开始支持协议格式检测,可以自动检测 OpenWire、STOMP、AMQP 和 MQTT。允许这四种类型的客户端共享一个传输。
2. 如何使用 AUTO 协议
- AUTO 使用 TCP
<tranportConnector name="auto" uri="auto://localhost:5671"/>
- AUTO 使用 SSL
<tranportConnector name="auto+ssl" uri="auto+ssl://localhost:5671"/>
- AUTO 使用 NIO
<tranportConnector name="auto+nio" uri="auto+nio://localhost:5671"/>
- AUTO 使用 NIO+SSL
<tranportConnector name="auto+nio+ssl" uri="auto+nio+ssl://localhost:5671"/>