- 为什么要引入MQ消息中间件
- 传统的系统之间直接调用在实际工程落地中存在许多问题
- 系统之间耦合比较严重.
- 面对大流量并发时,容易被冲垮.(每个接口模块的吞吐能力是有限的)
- 等待同步存在性能问题
- 为了解决上述的问题,所以引入MQ达到以下几个目标:
- 能够解耦: 要做到系统解耦,当新的模块接进来时,可以做到代码改动最小.
- 能够削峰: 设置流量缓冲池,可以让后端系统按照自身吞吐能力进行消费,不被冲垮.
- 能够异步: 强弱依赖梳理能将非关键调用链路的操作异步化并提升整体系统的吞吐能力.
-
MQ的处理流程
发送者把消息发送给消息服务器,消息服务器把消息存放在若干队列/主题topic中,在合适的时候,消息服务器会将消息转发给接受者,在这个过程中,发送和接受是异步的,也就是发送无需等待,而且发送者和接受者的生命周期没有必然关系;尤其是在发布pub/订阅sub模式下,也可以完成一对多的通信,即让一个消息有多个接受者. -
activeMQ两个端口
- java用的tcp端口: 61616
- activeMQ图形化后台管理系统界面端口:8161
- ActiveMQ启动暂停的方式
-
开启ActiveMQ
- 普通启动: 在ActiveMQ的bin目录下执行
./activemq start
- 按照不同的conf配置文件启动
./activemq start xbean:file:配置文件目录
- 带运行日志的启动方式: ActiveMQ的bin目录下执行
./activemq start > ../data/activemq.log
-
关闭ActiveMQ
在ActiveMQ的bin目录下执行./activemq stop
- ActiveMQ图形化界面
- 访问ActiveMQ图形化界面命令: 启动ActiveMQ后,访问http://ip: port, 本机上一般为localhost:8161,用户名密码为admin
- ActiveMQ中队列和主题topic的区别
- 在点对点的消息传送域中,目的地被称为队列queue
- 在发布订阅消息传送域中,目的地被称为主题topic
-
topic模式和queue模式比较
-
activeMQ的broker
相当于一个activeMQ的服务器实例.
broker其实就是实现了用代码的形式启动activeMQ将MQ嵌入到java代码中,以便随时用随时启动,在用的时候再去启动,这样能节省资源,也保证了可靠性. -
activeMQ broker使用代码
package com.atguigu.activemq.Embed; import org.apache.activemq.broker.BrokerService; public class EmbedBroker { public static void main(String[] args) throws Exception { // 将迷你版的activeMQ嵌入到java程序中 BrokerService brokerService = new BrokerService(); // jmx: Java Management Extensions 它是一个Java平台的管理和监控接口 brokerService.setUseJmx(true); brokerService.addConnector("tcp://localhost:61616"); brokerService.start(); } }
注: 启动该activeMQ服务,然后启动生产者和消费者便能消费消息.
-
activemq传输协议(重点是TCP和NIO)
-
TCP(Transmission Control Protocal 传输控制协议,默认)
- 默认的Broker(MQ服务器实例)配置,TCP的client监听端口为61616
- 在网路传输数据前,必须要序列化数据,消息是通过一个叫wire protocal的协议来序列化成字节流.默认情况下ActiveMQ把wire protocal叫做OpenWire,它的目的是促使网络上的数据快速交互.
- TCP的连接URL形式为: tcp:hostname:port?key=value&key=value 后面参数可选
- TCP传输的优点
- 可靠性高、稳定性强
- 高效性: 字节流方式传递,效率高
- 有效性、可用性: 应用广泛,支持任何平台
- 关于TCP协议的可配置参数参考activemq官网
-
NIO(New I/O API Protocal)
- NIO协议和TCP协议类似但是NIO协议更侧重于底层的访问操作,它允许开发人员对同一资源可有更多的client调用和服务端有更多的负载.
- 适合NIO协议的场景
- 可能有大量的client去连接Broker,一般情况下,大量的client去连接Broker是被操作系统的线程所限制的.因此,NIO的实现比TCP需要更少线程去运行,所以建议使用NIO协议.
- 可能对于Broker有一个很迟钝的网络传输,NIO比TCP提供更好的性能.
- NIO的连接URI形式: nio://hostname:port?key=value
- Transport Connector配置示例,参考activemq官网
- 使用NIO需要在activemq.xml配置文件中配置如下内容
<broker> ... <transportConnectors> <transportConnector name="nio" uri="nio://0.0.0.0:61616"/> </<transportConnectors> ... </broker>
-
AMQP(Advanced Message Queuing Protocal 高级消息队列协议)
- 一个提供同一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端和消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制.
比TCP协议的适用性更广.
- 一个提供同一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端和消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制.
-
stomp(Streaming Text Orientated Message Protocal 流文本定向消息协议)
一种为MOM(Message Oriented Middleware 面向消息的中间件)设计的简单文本协议. -
Secure Sockets Layer Protocal(SSL 安全套接字协议)
- URL形式: ssl://hostname:port?key=value
- 使用SSL需要在activemq.xml配置文件中配置如下内容
<broker> ... <transportConnectors> <transportConnector name="ssl" uri="ssl://localhost:61618?trace=true"/> </<transportConnectors> ... </broker>
-
mqtt(Message Queuing Telemetry Transport 消息队列遥测传输协议)
IBM开发的一个即使通讯协议,有可能成为物联网的重要组成部分.该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当作传感器和制动器(比如通过Twitter让房屋联网)的通信协议 -
ws(WebSockets)协议
用于前端 -
总结
- 使用activemq的NIO传输协议
-
修改activemq.xml配置文件
注: 端口不能冲突.原本openwire(即TCP)的端口为61616,因为使用了docker,容器端口映射没添加成功,所以为了演示NIO,NIO使用了61616端口. -
生产者和消费者代码只需要修改URL即可.其余代码参考:springboot整合activemq的queue/topic代码
server:
port: 6666
spring:
activemq:
# 只需要修改该行
broker-url: nio://localhost:61616
user: admin
password: admin
jms:
pub-sub-domain: true # true代表topic,false代表queue
# 自己定义的主题名称
mytopic: boot-activemq-topic
- NIO加强
-
默认的NIO是基于TCP的,想要让NIO支持其它协议,可以使用auto+nio
-
修改activemq.xml配置文件(注意端口不要冲突)
<transportConnector name="auto+nio" uri="auto+nio://0.0.0.0:61606?maximumConnections=1000" />
-
在代码中修改url为tcp/nio或其他协议即可使用相应协议
server: port: 6666 spring: activemq: # 切换BIO的TCP协议和NIO的TCP协议只需要修改下面一行即可,如果使用其他协议,java代码不太一样. # broker-url: nio://localhost:61616 broker-url: tcp://localhost:61616 user: admin password: admin jms: pub-sub-domain: true # true代表topic,false代表queue # 自己定义的主题名称 mytopic: boot-activemq-topic
注: 其余代码参考:springboot整合activemq的queue/topic代码
- activemq消息持久化: mq服务器宕机了