映像笔记地址:https://app.yinxiang.com/fx/eca4918e-9a79-45c8-ad10-5cf070325320
3. RabiitMQ 配置
3.1RabbitMQ 管理命令行
# 1.服务启动相关
systemctl start|restart|stop|status rabbitmq-server
# 2.管理命令行 用来在不使用web管理界面情况下命令操作RabbitMQ
rabbitmqctl help 可以查看更多命令
# 3.插件管理命令行
rabbitmq-plugins enable|list|disable
3.2 web管理界面介绍
3.2.1 overview概览
-
connections:无论生产者还是消费者,都需要与RabbitMQ建立连接后才可以完成消息的生产和消费,在这里可以查看连接情况
-
channels:通道,建立连接后,会形成通道,消息的投递获取依赖通道。
-
Exchanges:交换机,用来实现消息的路由
-
Queues:队列,即消息队列,消息存放在队列中,等待消费,消费后被移除队列 。
3.2.2 Admin用户和虚拟主机管理
1. 添加用户
上面的Tags选项,其实是指定用户的角色,可选的有以下几个:
-
超级管理员(administrator)
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
-
监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
-
策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
-
普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
-
其他
无法登陆管理控制台,通常就是普通的生产者和消费者。
2. 创建虚拟主机

3. 绑定虚拟主机和用户
创建好虚拟主机,我们还要给用户添加访问权限:
点击添加好的虚拟主机:
4.RabbitMQ 的第一个程序
4.0 AMQP协议的回顾
注意:(消息不一定要放在交换机中也可以直接发给Quene,根据具体的消息模型而定)。
4.1 RabbitMQ支持的消息模型
4.2 引入依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.2</version>
</dependency>
4.3 第一种模型(直连)
在上图的模型中,有以下概念:
-
P:生产者,也就是要发送消息的程序
-
C:消费者:消息的接受者,会一直等待消息到来。
-
queue:消息队列,图中红色部分。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。
1. 开发生产者
package com.ztb.queues;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* Created by ztb on 2020/6/10
**/
public class Provider{
//生产消息
@Test
public void testSendMessage() throws IOException, TimeoutException {
//1,生产者与服务器建立连接,创建连接MQ的工厂对象
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置连接rabbitmq的虚拟主机
connectionFactory.setHost("192.168.41.128");
//3.设置端口号
connectionFactory.setPort(5672);
//4.设置连接的虚拟主机
connectionFactory.setVirtualHost("/ems");
//5.设置虚拟主机的用户名和密码
connectionFactory.setUsername("ems");
connectionFactory.setPassword("123456");
//6.获取连接对象
Connection connection = connectionFactory.newConnection();
//7.获取连接中的通道
Channel channel = connection.createChannel();
//8.通道绑定对应的消息队列
//参数1:队列名称,如果队列不存在则直接创建
//参数2:定义队列的特性是否会持久化。true 代表持久化队列,false则代表下一次重启队列则会删除队列
//参数3:是否独占队列。(只允许当前连接可用)
//参数4:是否在消费完成后自动删除消息队列。
//参数5:额外参数
channel.queueDeclare("hello",false,false,false,null);
//发布消息
//参数1:交换机名称 参数2:队列名称 参数3:传递消息额外设置 消息4:消息的具体内容
channel.basicPublish("","hello",null,"hello ,rabbitmq".getBytes());
//关闭通道,关闭连接
channel.close();
connection.close();
}
}
2.开发消费者
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.15.0.9");
connectionFactory.setPort(5672);
connectionFactory.setUsername("ems");
connectionFactory.setPassword("123");
connectionFactory.setVirtualHost("/ems");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("hello", true, false, false, null);
channel.basicConsume("hello",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println(new String(body));
}
});
3.参数的说明
channel.queueDeclare("hello",true,false,false,null);
'参数1':用来声明通道对应的队列
'参数2':用来指定是否持久化队列
'参数3':用来指定是否独占队列
'参数4':用来指定是否自动删除队列
'参数5':对队列的额外配置
4.4 第二种模型(work quene)

channel.queueDeclare("hello", true, false, false, null);
for (int i = 0; i < 10; i++) {
channel.basicPublish("", "hello", null, (i+"====>:我是消息").getBytes());
}
2.开发消费者-1
channel.queueDeclare("hello",true,false,false,null);
channel.basicConsume("hello",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1: "+new String(body));
}
});
3.开发消费者-2
channel.queueDeclare("hello",true,false,false,null);
channel.basicConsume("hello",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
try {
Thread.sleep(1000); //处理消息比较慢 一秒处理一个消息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者2: "+new String(body));
}
});
4.测试结果
总结:默认情况下,RabbitMQ将按顺序将每个消息发送给下一个使用者。平均而言,每个消费者都会收到相同数量的消息。这种分发消息的方式称为循环。
5.消息自动确认机制
channel.basicQos(1);//一次只接受一条未确认的消息
//参数2:关闭自动确认消息
channel.basicConsume("hello",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1: "+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);//手动确认消息
}
});
-
设置通道一次只能消费一个消息
-
关闭消息的自动确认,开启手动确认消息