大伙可以到我的RabbitMQ专栏获取更多信息
概述
本篇将要通过一个Demo来进一步的了解RabbitMQ,关于RabbitMQ的基本介绍可以参考我的上一篇文章:初识RabbitMQ:RabbitMQ基本概念和运行方式
控制台的基本使用
怎么安装和开启RabbitMQ控制台就不在此讨论了,网上相关文档有很多QAQ
登陆控制台
开启控制台后,打开控制台,控制台地址默认关口是15672:http://localhost:15672/#/
默认用户账号密码:guest/guest
登陆后:
控制台基本介绍
Overview:MQ运行情况概览
- 队列中Message的情况图表
- 当前MQ节点的概览:连接数、erlang processes、内存磁盘情况
- 当前MQ占用端口列表
- 导入导出配置:方便MQ的迁移等工作
Connections:当前RabbitMQ broker创建的connection情况
Channels:当前连接到MQ的通道情况
Exchanges:MQ所有交换机列表,包含了所属的用户、vhost信息以及当前交换机处理message的情况
Queues:所有队列的情况概览
Admin:
- 创建用户
- 创建vhost
- 给用户赋权
- 集群信息
- ......
创建用户
指定用户名/密码以及用户的身份Tag:
- management :访问 management plugin;
- policymaker :访问 management plugin 和管理自己 vhosts 的策略和参数;
- monitoring :访问 management plugin 和查看所有配置和通道以及节点信息;
- administrator :一切权限;
- None :无配置
none
不能访问 management plugin
management
用户可以通过AMQP做的任何事外加:
列出自己可以通过AMQP登入的virtual hosts
查看自己的virtual hosts中的queues, exchanges 和 bindings
查看和关闭自己的channels 和 connections
查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动。
policymaker
management可以做的任何事外加:
查看、创建和删除自己的virtual hosts所属的policies和parameters
monitoring
management可以做的任何事外加:
列出所有virtual hosts,包括他们不能登录的virtual hosts
查看其他用户的connections和channels
查看节点级别的数据如clustering和memory使用情况
查看真正的关于所有virtual hosts的全局的统计信息
administrator
policymaker和monitoring可以做的任何事外加:
创建和删除virtual hosts
查看、创建和删除users
查看创建和删除permissions
关闭其他用户的connections
根据需要选择不同的用户身份创建用户就好了。
创建Virtual Hosts
默认的vhost为 "/",vhost的创建以 "/" 开头,如:"/LeoLee"。
通常情况下vhost的命名带有一定的业务含义:如 "/LeoLee/dev" 可以认为是LeoLee这个系统的dev环境使用的vhost。
给用户赋予对应vhost的权限
Current permissions表格显示的是当前用户的所使用的vhost以及对应的使用权限
点击一个用户
在箭头处选择一个vhost,分别设置该vhost的configure、write、read三个权限授予当前用户,".*" 代表所有权限。
set permission保存当前权限设置。
7大工作模式之简单模式(Hello world)
1.创建客户端
本人为了方便,创建了一个多模块的Maven项目
项目结构如下:
在Maven的父module中POM文件引入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.leolee.rabbitmq</groupId>
<artifactId>rabbitmq-test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>RabbitMQ-producer</module>
<module>RabbitMQ-consumer</module>
</modules>
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.编写生产者
生产者向MQ发送消息步骤如下:
- 创建连接工厂
- 设置连接参数:账号密码,MQ地址端口等
- 创建指向MQ的Connection
- 创建Connection中的Channel
- 创建消息队列Queue并设置相关参数
- 发送数据
- 释放连接资源
package com.leolee.rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @ClassName ProducerHelloWorld
* @Description: MQ生产者
* @Author LeoLee
* @Date 2020/11/5
* @Version V1.0
**/
public class ProducerHelloWorld {
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置参数
connectionFactory.setHost("127.0.0.1");//默认值为localhost
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/LeoLee");//默认值为:/
connectionFactory.setUsername("LeoLee");
connectionFactory.setPassword("lyl512240816");
//3.创建连接 connection
Connection connection = connectionFactory.newConnection();
//4.创建channel
Channel channel = connection.createChannel();
//5.创建队列queue(由于简单模式不需要Exchange,其实是使用默认的交换机,所以消息直接入队列)
/*
String queue:队列名称
boolean durable:是否持久化
boolean exclusive: 有如下两个意义
是否独占,只有一个消费者监听这个队列
当connection关闭时,是否删除队列
boolean autoDelete:是否自动删除,当没有消费者的时候自动删除
Map<String, Object> arguments: 一些配置参数
*/
//如果没有一个名字叫Hello_world的队列,则会创建,如果存在该队列,则复用
channel.queueDeclare("Hello_world", false, false, false, null);
//6.发送消息
/*
String exchange:交换机名称,简单模式下交换机使用默认的 ""
String routingKey:路由名称,简单模式下就是队列名称
boolean mandatory:
boolean immediate:
BasicProperties props:配置信息
byte[] body:发送的消息数据
*/
String msg = "Hello RabbitMQ";
channel.basicPublish("", "Hello_world", null, msg.getBytes());
//7.释放资源
channel.close();
connection.close();
}
}
3.编写消费者
消费这从MQ消费消息步骤:
- 创建连接工厂
- 设置连接参数:账号密码,MQ地址端口等
- 创建从MQ获取消息的Connection
- 创建Connection中的Channel
- 创建消息队列Queue并设置相关参数(可选,此处可写可不写)
- 接收消息(消费消息):接收到消息后并回调本地方法
- 消费者不需要关闭连接,不然无法完成接收到消息后对MQ的消息确认工作
package com.leolee.rabbitmq;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @ClassName ConsumerHelloWorld
* @Description: MQ消费者
* @Author LeoLee
* @Date 2020/11/5
* @Version V1.0
**/
public class ConsumerHelloWorld {
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置参数
connectionFactory.setHost("127.0.0.1");//默认值为localhost
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/LeoLee");//默认值为:/
connectionFactory.setUsername("LeoLee");
connectionFactory.setPassword("lyl512240816");
//3.创建连接 connection
Connection connection = connectionFactory.newConnection();
//4.创建channel
Channel channel = connection.createChannel();
//5.创建队列queue(由于简单模式不需要Exchange,其实是使用默认的交换机,所以消息直接入队列),消费者可以不需要创建队列,但是创建了也不影响
/*
String queue:队列名称
boolean durable:是否持久化
boolean exclusive: 有如下两个意义
是否独占,只有一个消费者监听这个队列
当connection关闭时,是否删除队列
boolean autoDelete:是否自动删除,当没有消费者的时候自动删除
Map<String, Object> arguments: 一些配置参数
*/
//如果没有一个名字叫Hello_world的队列,则会创建,如果存在该队列,则复用
//channel.queueDeclare("Hello_world", false, false, false, null);
//6.接收消息
/*
* String queue:队列名称
* boolean autoAck:是否自动确认,当消费者收到消息之后会自动给MQ一个回执,告诉MQ消息已经收到
* Consumer callback:回调方法
*/
Consumer consumer = new DefaultConsumer(channel){
/*
* 功能描述: <br>
* 〈回调方法〉当客户端收到消息并向MQ确认消息已经收到,将回调该方法
* @Param: [consumerTag消息唯一标识,
* envelope获取一些信息,包含交换机信息、routing key...等,
* properties配置信息,生产者发送消息时候的配置,
* body数据]
* @Return: void
* @Author: LeoLee
* @Date: 2020/11/5 11:56
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("consumerTag:" + consumerTag);
System.out.println("envelope.exchange:" + envelope.getExchange());
System.out.println("envelope.routingKey:" + envelope.getRoutingKey());
System.out.println("properties:" + properties);
System.out.println("body:" + new String(body));
}
};
channel.basicConsume("Hello_world", true, consumer);
//7.消费者不需要关闭资源,不然无法完成自动确认
}
}
4.运行Demo
生产者执行之后回向MQ推送一条消息:
由于发送消息了之后,生产者关闭了连接,释放了资源,所以在控制台看到的Connection和Channel为0
执行消费者代码消费消息:
成功获取到了MQ中的消息
由控制台信息可以得出,消息成功被消费者读取,MQ队列中已经没有任何message,并且Connection、Channel、Queue均为1,说明客户端连接还在保持