一、什么是MQ
MQ(message Quene):翻译为消息队列,通过典型的生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,轻松的实现系统间的解耦,别名 消息中间件 通过利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成
二、RabbitMQ
基于AMQP协议,erlang语言开发,是部署最广泛的开源消息中间件,是最受欢迎的开源消息中间件之一。
AMQP:Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
三、RabbitMQ管理命令行
1、服务启动相关
systemctl staart|restart|stop|status rabbitmq-server
2、管理命令行 用来在不使用web管理界面情况下命令操作RabbitMQ
rabbitmqctl help 可以查看更多命令
3、插件管理命令行
rabbitmq-plugins enable|list|disable
rabbitmq-plugins查看可执行的命令
4、是
四、RabbitMQ基本概念
- publisher:消息的生产者
- Broker:接收和分发消息的应用,我们在运行的Rabbitmq-server就是Message Broker
- Virtual Host:虚拟主机,里面包含AMQP的基本组件,当多个用户使用同一个RabbitMQ-server时,我们可以为每个用户创建一个虚拟主机,它们包含自己的Exchange和Queue
- Exchange:交换机,用来指定消息要分发到那条队列中去
- Binding:Exchange和队列之间的虚拟连接
- Queue:消息队列,生产者生产的消息在此处等待被消费者的消费
- Connection: publisher/consumer和broker之间的TCP连接。断开连接的操作只会在client端进行,Broker不会断开连接,除非出现网络故障或broker服务出现问题。
- Channel: 如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。
五、RabbitMQ支持的消息模型及简单直连模型代码编写
简单直连的代码编写
依赖引入
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
生产者代码
// 创建连接到mq的连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 设置连接rabbitmq主机
connectionFactory.setHost("运行RabbitMQ服务的主机的IP");
// 设置端口号
connectionFactory.setPort(5672);
// 设置连接那个虚拟主机
connectionFactory.setVirtualHost("/ems");
// 设置访问虚拟主机的用户名和密码
connectionFactory.setUsername("ems");
connectionFactory.setPassword("123");
// 获取连接对象
Connection connection = connectionFactory.newConnection();
// 获取连接通道
Channel channel = connection.createChannel();
// 通道绑定对应消息队列
// queueDeclare参数 1、队列名称(不过不存在自动创建) 2、用来定义队列是否要持久化(仅针对队列,队列内的消息不会持久化)
// 3、是否要独占队列 4、是否在消费完成后自动删除队列 5、额外附加参数
channel.queueDeclare("hello",false,false,false,null);
// 发布消息
// 1、交换机名称 2、队列名称 3、传递消息额外设置如MessageProperties.PERSISTENT_TEXT_PLAIN可以持久化消息 4、消息的具体内容
channel.basicPublish("","hello",null,"hello rabbitmq".getBytes());
// 关闭通道
channel.close();
// 关闭连接
connection.close();
消费者代码
// 创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 绑定mq服务
connectionFactory.setHost("运行RabbitMQ服务的主机的IP");
connectionFactory.setPort(5672);
// 绑定虚拟主机
connectionFactory.setVirtualHost("/ems");
connectionFactory.setUsername("ems");
connectionFactory.setPassword("123");
// 获取连接对象
Connection connection = connectionFactory.newConnection();
// 获取连接通道
Channel channel = connection.createChannel();
// 为通道绑定对应的消息队列
channel.queueDeclare("hello",false,false,false,null);
// 消费消息
// 1、消费队列名称 2、开始消息的自动确认机制 3、消费时的回调接口
channel.basicConsume("hello",true,new DefaultConsumer(channel){
// byte[] body :消息队列中取出的消息
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("Coustomer=>"+new String(body));
}
});