RabbitMQ常用操作命令和入门案例(一对一的简单模式)
一、RabbitMQ常用操作命令
常见命令列表:
# 前台启动Erlang VM和RabbitMQ
rabbitmq-server
# 后台启动
rabbitmq-server -detached
# 停止RabbitMQ和Erlang VM
rabbitmqctl stop
# 查看所有队列
rabbitmqctl list_queues
# 查看所有虚拟主机
rabbitmqctl list_vhosts
# 在Erlang VM运行的情况下启动RabbitMQ应用
rabbitmqctl start_app
rabbitmqctl stop_app
# 查看节点状态
rabbitmqctl status
# 查看所有可用的插件
rabbitmq-plugins list
# 启用插件
rabbitmq-plugins enable <plugin-name>
# 停用插件
rabbitmq-plugins disable <plugin-name>
# 添加用户
rabbitmqctl add_user username password
# 列出所有用户:
rabbitmqctl list_users
# 删除用户:
rabbitmqctl delete_user username
# 清除用户权限:
rabbitmqctl clear_permissions -p vhostpath username
# 列出用户权限:
rabbitmqctl list_user_permissions username
# 修改密码:
rabbitmqctl change_password username newpassword
# 设置用户权限:
rabbitmqctl set_permissions -p vhostpath username ".*" ".*" ".*"
# 创建虚拟主机:
rabbitmqctl add_vhost vhostpath
# 列出所以虚拟主机:
rabbitmqctl list_vhosts
# 列出虚拟主机上的所有权限:
rabbitmqctl list_permissions -p vhostpath
# 删除虚拟主机:
rabbitmqctl delete_vhost vhost vhostpath
# 移除所有数据,要在 rabbitmqctl stop_app 之后使用:
rabbitmqctl reset
操作案例:
前台启动Erlang VM和RabbitMQ
停止RabbitMQ和Erlang VM
多出一个守护进程:epmd负责端口通信和内存分配
查看所有队列/查看rabbitmqctl 帮助命令
查看 “查看所有队列” 命令 的帮助命令
查看所有虚拟主机
查看所有虚拟主机(使用参数–formatter pretty_table)
查看节点状态
[root@RabbitMQ ~]# rabbitmqctl status
Status of node rabbit@RabbitMQ ...
Runtime
OS PID: 7894
OS: Linux
Uptime (seconds): 1017
RabbitMQ version: 3.8.5
Node name: rabbit@RabbitMQ
Erlang configuration: Erlang/OTP 23 [erts-11.0.2] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:64] [hipe]
Erlang processes: 439 used, 1048576 limit
Scheduler run queue: 1
Cluster heartbeat timeout (net_ticktime): 60
Plugins
Enabled plugin file: /etc/rabbitmq/enabled_plugins
Enabled plugins:
* rabbitmq_management
* amqp_client
* rabbitmq_web_dispatch
* cowboy
* cowlib
* rabbitmq_management_agent
Data directory
Node data directory: /var/lib/rabbitmq/mnesia/rabbit@RabbitMQ
Raft data directory: /var/lib/rabbitmq/mnesia/rabbit@RabbitMQ/quorum/rabbit@RabbitMQ
Config files
Log file(s)
* /var/log/rabbitmq/rabbit@RabbitMQ.log
* /var/log/rabbitmq/rabbit@RabbitMQ_upgrade.log
Alarms
(none)
Memory
Calculation strategy: rss
Memory high watermark setting: 0.4 of available memory, computed to: 0.4079 gb
code: 0.0277 gb (31.81 %)
other_proc: 0.0264 gb (30.33 %)
other_system: 0.0122 gb (14.07 %)
allocated_unused: 0.0115 gb (13.24 %)
other_ets: 0.0032 gb (3.67 %)
reserved_unallocated: 0.0026 gb (2.99 %)
plugins: 0.0015 gb (1.71 %)
atom: 0.0014 gb (1.63 %)
mgmt_db: 0.0002 gb (0.2 %)
binary: 0.0001 gb (0.14 %)
mnesia: 0.0001 gb (0.09 %)
metrics: 0.0001 gb (0.07 %)
msg_index: 0.0 gb (0.03 %)
quorum_ets: 0.0 gb (0.02 %)
connection_other: 0.0 gb (0.0 %)
connection_channels: 0.0 gb (0.0 %)
connection_readers: 0.0 gb (0.0 %)
connection_writers: 0.0 gb (0.0 %)
queue_procs: 0.0 gb (0.0 %)
queue_slave_procs: 0.0 gb (0.0 %)
quorum_queue_procs: 0.0 gb (0.0 %)
File Descriptors
Total: 2, limit: 927
Sockets: 0, limit: 832
Free Disk Space
Low free disk space watermark: 0.05 gb
Free disk space: 15.0882 gb
Totals
Connection count: 0
Queue count: 0
Virtual host count: 1
Listeners
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: [::], port: 15672, protocol: http, purpose: HTTP API
插件操作
用户操作
权限操作
二、RabbitMQ工作流程概述
1、生产者发送消息的流程
1. 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
2. 生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
3. 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
4. 生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来
5. 生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息
6. 相应的交换器根据接收到的 routingKey 查找相匹配的队列。
7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。
8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
9. 关闭信道。
10. 关闭连接。
2、消费者接收消息的过程
1. 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
2. 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作
3. 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
4. 消费者确认( ack) 接收到的消息。
5. RabbitMQ 从队列中删除相应己经被确认的消息。
6. 关闭信道。
7. 关闭连接。
3、案例(一对一的简单模式)
生产者直接发送消息给RabbitMQ,另一端消费。未定义和指定Exchange的情况下,使用的是AMQP default这个内置的Exchange。
3.1 编写pom.xml,引入rabbitmq依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dabing</groupId>
<artifactId>RabbitMQTest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
</project>
3.2 编写消费者端TestProducter .java,向队列发送消息”hello rabbitmq“
public class TestProducter {
public static void main(String[] args) throws IOException, TimeoutException {
// 1. 获取连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 通过属性设置(也可以通过uri设置)
// 2. 设置主机名 hostname
factory.setHost("192.168.80.15");
// 3. 设置虚拟主机名称 /在url中的转义字符 %2f
factory.setVirtualHost("/");
// 4. 设置用户名和密码
factory.setUsername("root");
// 密码
factory.setPassword("123456");
// amqp的端口号
factory.setPort(5672);
// 5. 建立TCP连接
Connection connection = factory.newConnection();
// 6. 获取通道
Channel channel = connection.createChannel();
// 7. 声明消息队列
// 参数一:消息队列名称
// 参数二:是否是持久化的(重启后,消息队列是否存在)
// 参数三:是否是排他的(共享)
// 参数四:是否是自动删除的(没有客户端订阅监听,系统自动删除)
// 参数五:消息队列的属性信息。使用默认值;
channel.queueDeclare("queue.dabing", false, false, true, null);
// 8. 声明交换器
// 参数一:交换器的名称
// 参数二:交换器的类型
// 参数三:交换器是否是持久化的
// 参数四:交换器是否是自动删除的
// 参数五:交换器的属性map集合
channel.exchangeDeclare("ex.dabing", BuiltinExchangeType.DIRECT, false, false, null);
// 9. 将交换器和消息队列绑定,并指定路由键
//参数三:路由key
channel.queueBind("queue.dabing", "ex.dabing", "testmq");
// 10. 发送消息
// 参数一:交换器的名字
// 参数二:该消息的路由键
// 参数三:该消息的属性BasicProperties对象
// 参数四:消息的字节数组
channel.basicPublish("ex.dabing", "testmq", null, "hello rabbitmq".getBytes());
// 11. 关闭通道
channel.close();
// 关闭连接
connection.close();
}
}
运行后,web端查看
交换,路由key和队列的对应关系
3.3 编写TestGetConsumer.java(拉取消息)
public class TestGetConsumer {
public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException, IOException, TimeoutException {
// 1. 获取连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2. 通过uri设置(也可以通过属性设置)
// 指定协议: amqp://
// 指定用户名 root
// 指定密码 123456
// 指定host 192.168.80.15
// 指定端口号 5672
// 指定虚拟主机 %2f 表示:斜杠
factory.setUri("amqp://root:123456@192.168.80.15:5672/%2f");
// 3. 建立TCP连接
final Connection connection = factory.newConnection();
System.out.println(connection.getClass());
// 4. 获取通道
final Channel channel = connection.createChannel();
// 5. 拉消息模式
// 参数一:指定从哪个消费者消费消息
// 参数二:指定是否自动确认消息 true表示自动确认
final GetResponse getResponse = channel.basicGet("queue.dabing", true);
// 6. 获取消息体 hello world 1
final byte[] body = getResponse.getBody();
System.out.println("body:"+new String(body));
channel.close();
connection.close();
}
}
运行程序 TestGetConsumer.java
3.4 编写TestPushConsumeConsumer.java(推消息)
public class TestPushConsumeConsumer {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setUri("amqp://root:123456@192.168.80.15:5672/%2f");
final Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();
// 确保MQ中有该队列,如果没有则创建
channel.queueDeclare("queue.dabing", false, false, true, null);
DeliverCallback callback = new DeliverCallback() {
@Override
public void handle(String consumerTag, Delivery message) throws IOException {
System.out.println(new String(message.getBody()));
}
};
// 监听消息,一旦有消息推送过来,就调用第一个lambda表达式
channel.basicConsume("queue.dabing", (consumerTag, message) -> {
System.out.println(new String(message.getBody()));
}, (consumerTag) -> {});
//channel.close();
//connection.close();
}
}