https://blog.csdn.net/qq_35387940/article/details/100514134
https://www.bilibili.com/video/BV1gW411H7Az?p=1
目录
0. 官方手册及所有模型
https://www.rabbitmq.com/getstarted.html
0.5 AMQP协议
1. 消息队列的作用:解耦;削峰;异步
1.1 解耦:不需要考虑消费者的问题。
1.2 异步:更节省时间。
1.3 削峰:减轻数据库压力。
2. RabbitMQ的安装:
2.1 下载Erlang
- erlang安装完成需要配置erlang环境变量: ERLANG_HOME=D:\xxxxxxx\erl9.3
- 在path中添加%ERLANG_HOME%\bin
2.2 下载RabbitMQ
https://www.rabbitmq.com/install-windows.html#installer
- cmd命令:激活web插件
rabbitmq-plugins enable rabbitmq_management
- 进入管理后台:http://localhost:15672
- 输入用户名:guest,密码:guest
2.3 添加用户
2.4 添加Virtual Hosts
- 就相当于添加数据库。
- 像mysql有数据库的概念并且可以指定用户对库和表等操作的权限。那RabbitMQ呢?
- RabbitMQ也有类似的权限管理。在RabbitMQ中可以虚拟消息服务器VirtualHost
- 每个VirtualHost相当月一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互隔离的。exchange、queue、message不能互通。
2.5 对用户进行授权
- 就可以用新的账号和密码进行登录了
3. RabbitMQ 之 简单队列
3.1 简单队列的模型
3.2 代码演示,生产者,消费者
- maven,pom文件中的依赖。
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
- 创建一个工具类:
public class ConnectionUtils {
public static Connection getConnection() throws IOException, TimeoutException {
// 定义一个连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 服务地址
factory.setHost("127.0.0.1");
factory.setPort(5672); // AMQP 5672
factory.setVirtualHost("/vhost_mason");
factory.setUsername("user_mason");
factory.setPassword("123456");
return factory.newConnection(); // 获取连接
}
}
- 进行消息的发送
public class Send {
private static final String QUEUE_NAME = "test_simple_queue";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();// 获取连接
Channel channel = connection.createChannel(); // 从连接中获取通道
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String msg = "hello simple !";
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("--send msg:" + msg);
channel.close();
connection.close();
}
}
- 运行生产者代码:
- 点进去
- 看到里面的信息就是:hello simple !
- 写消费者的代码:
public class Receive {
private static final String QUEUE_NAME = "test_simple_queue";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection(); // 获取连接
Channel channel = connection.createChannel();
// 队列声明
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 定义消费者
DefaultConsumer consumer = new DefaultConsumer(channel) {
// 获取到达的消息
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String msgString = new String(body, "utf-8");
System.out.println("recv:" + msgString);
}
};
// 监听队列。
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
- 运行。就会收到生产者发送的消息。
3.3 简单队列的缺点
- 耦合性高,一一对应的关系。
- 队列名生产者和消费者需要同时变更。
4. RabbitMQ 之 工作队列
4.1 工作队列的模型
4.2 为什么出现工作队列
- 消费的时间>生产的实现,所以增加消费者的数量
4.3 轮询分发方式(一人一个不要抢,大锅饭)
- 生产者:
public class Send {
private static final String QUEUE_NAME = "test_work_queue";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
for (int i = 0; i < 50; i++) {
String msg = "hello " + i;
System.out.println("[Work Queue] send:" + msg);
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
Thread.sleep(i * 20);
}
channel.close();
connection.close(