RabbitMQ的模式
本文简单使用前五种RabbitMQ模式。。
完整请参考:https://www.rabbitmq.com/getstarted.html
1、 "Hello World!"简单模式
P:表示Producer,即消息的产生者
红色的:queue,即消息队列 用于存储消息
C:consumer,消费者,即消费消息的
特点:一个生产者,一个队列,一个消费者
使用maven项目简单使用简单模式。
(1)开启rabbitMQ。
systemctl start rabbitmq-server
使用浏览器访问rabbitMQ图形化界面:
rabbitMQ所在的ip:15672
rabitmq初始登录账号与密码都是:guest
(2)创建测试类
在同一个项目中创建两个子工程:producer,connection
子项目建maven项目即可。
父工程的pom.xml中引入rabbitmq依赖
<groupId>com.kkk</groupId>
<artifactId>java_rabbitMQ_jiandan</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>producer</module>
<module>connection</module>
</modules>
<dependencies>
<!--引入rabbitMQ的依赖-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
(3)producer工程内创建消息生产者测试类:
public class ProducerTest {
/**
*简单模式
* */
public static void main(String[] args) throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
//连接rabbitMQ,需要写自己rabbitMQ的地址
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//创建队列
/**
* String queue, 队列名称
* boolean durable, 是否持久化
* boolean exclusive, 是否独占的,,即只允许一个 设为false
* boolean autoDelete, 是否自动删除 ,如果长时间没有发生消息,自动删除
* Map<String, Object> arguments 额外参数
* */
channel.queueDeclare("ban_queue",true,false,true,null);
//产生消息
/**
* String exchange, 交换机的名称 使用默认的则填""
* String routingKey, 路由的key,如果没有交换机的绑定,则填队列的名称
* BasicProperties props, 消息的额外配置 ,java没有填null
* byte[] body 参数,即消息的内容
* */
String ss="从前有座山a";
channel.basicPublish("","ban_queue",null,ss.getBytes());
}
}
(4)consumer工程内创建消息消费者测试类:
public class ConnectionTest {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body为接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue",true,callback);
}
}
2、Work queues 工作者模式:
P:表示Producer,即消息的产生者
红色的:queue,即消息队列 用于存储消息
C1,c2:consumer,消费者,即消费消息的
特点:
1. 一个生产者
2. 有多个消费。
3. 同一个队列。
4. 这些消费者之间存在竞争关系。
用处:
比如批量处理上. rabbitMQ里面积压了大量的消息。
(1)producer生产者代码:
public class ProducerTest {
/**
*工作者模式
*/
public static void main(String[] args) throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//创建队列
/**
* String queue, 队列名称
* boolean durable, 是否持久化
* boolean exclusive, 是否独占的,,即只允许一个 设为false
* boolean autoDelete, 是否自动删除 ,如果长时间没有发生消息,自动删除
* Map<String, Object> arguments 额外参数
* */
channel.queueDeclare("ban_queue_work",true,false,true,null);
//产生消息
/**
* String exchange, 交换机的名称 需要使用默认的则填""
* String routingKey, 路由的key,如果没有交换机的绑定,则填队列的名称
* BasicProperties props, 消息的额外配置 ,没有填null
* byte[] body 参数,即消息的内容
* */
for (int i = 0; i < 10; i++) {//生产十条消息
String ss="从前有座山"+i;
channel.basicPublish("","ban_queue_work",null,ss.getBytes());
}
}
}
(2)consumer消费者01代码:
public class ConnectionTest01 {
/**
* 工作者模式
* */
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_work",true,callback);
}
}
(2)consumer消费者02代码:
public class ConnectionTest02 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_work",true,callback);
}
}
3、Publish/Subscribe 发布订阅模式
P:表示Producer,即消息的产生者
红色的:queue,即消息队列 用于存储消息
C1,c2:consumer,消费者,即消费消息的
x:交换机,用于将信息从消费者转发到队列
特点:
1. 一个生产者
2. 有一个交换机。
3. 有多个消费者。
4. 有多个队列。
***与direct和topic区别在于交换机的type不同
(1)producer生产者代码
public class ProducerTest {
public static void main(String[] args) throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//创建队列
/**
* String queue, 队列名称
* boolean durable, 是否持久化
* boolean exclusive, 是否独占的,,即只允许一个 设为false
* boolean autoDelete, 是否自动删除 ,如果长时间没有发生消息,自动删除
* Map<String, Object> arguments 额外参数
* */
channel.queueDeclare("ban_queue_fanout01",true,false,false,null);
channel.queueDeclare("ban_queue_fanout02",true,false,false,null);
//创建交换机
//String exchange, String type, boolean durable
channel.exchangeDeclare("ban_exchange", BuiltinExchangeType.FANOUT,true);
//绑定队列
//String queue, String exchange, String routingKey
channel.queueBind("ban_queue_fanout01","ban_exchange","");
channel.queueBind("ban_queue_fanout02","ban_exchange","");
//产生消息
/**
* String exchange, 交换机的名称 使用默认的则填""
* String routingKey, 路由的key,如果没有交换机的绑定,则填队列的名称
* BasicProperties props, 消息的额外配置 ,没有填null
* byte[] body 参数,即消息的内容
* */
for (int i = 0; i < 10; i++) {
String ss="从前有座山"+i;
channel.basicPublish("ban_exchange","",null,ss.getBytes());
}
}
}
(2)consumer消费者01代码
public class ConnectionTest01 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_fanout01",true,callback);
}
}
(3)consumer消费者02代码
public class ConnectionTest02 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_fanout02",true,callback);
}
}
4、 Routing 路由模式
特点:
1.一个生产者
2.多个消费者
3.多个队列。
4.一个交换机 用于转发消息。
5.routekey:路由key 只要routekey匹配的消息可以到达对应队列(即图中的error等)。
(1)producer生产者代码
(为了方便理解,此代码未抽取交换机名称和队列名称,可自行抽取出来单独定义)
public class ProducerTest {
public static void main(String[] args) throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//创建队列
/**
* String queue, 队列名称
* boolean durable, 是否持久化
* boolean exclusive, 是否独占的,,即只允许一个 设为false
* boolean autoDelete, 是否自动删除 ,如果长时间没有发生消息,自动删除
* Map<String, Object> arguments 额外参数
* */
channel.queueDeclare("ban_queue_direct01",true,false,true,null);
channel.queueDeclare("ban_queue_direct02",true,false,true,null);
//创建交换机
//String exchange, String type, boolean durable
channel.exchangeDeclare("ban_exchange_direct", BuiltinExchangeType.DIRECT,true);
//绑定队列
//String queue, String exchange, String routingKey
channel.queueBind("ban_queue_direct01","ban_exchange_direct","error");
channel.queueBind("ban_queue_direct02","ban_exchange_direct","info");
channel.queueBind("ban_queue_direct02","ban_exchange_direct","error");
channel.queueBind("ban_queue_direct02","ban_exchange_direct","warning");
//产生消息
/**
* String exchange, 交换机的名称 使用默认的则填""
* String routingKey, 路由的key,如果没有交换机的绑定,则填队列的名称
* BasicProperties props, 消息的额外配置 ,没有填null
* byte[] body 参数,即消息的内容
* */
// String ss="杨可真是美若天仙了,不愧是舒隆振的老婆!";
for (int i = 0; i < 10; i++) {
String ss="从前有座山"+i;
channel.basicPublish("ban_exchange_direct","error",null,ss.getBytes());
}
}
}
(2)consumer消费者01代码
public class ConnectionTest01 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_direct01",true,callback);
}
}
(3)consumer消费者02代码
public class ConnectionTest02 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_direct02",true,callback);
}
}
5、Topic 主题模式
特点:
1.一个生产者
2.多个消费者
3.多个队列。
4.一个交换机 用于转发消息。
5.routekey:路由key 只要routekey匹配的消息可以到达对应队列(即图中的*.orange.*等)。
绑定按照通配符的模式:
*: 统配一个单词。
#: 统配n个单词(包含0,1,2......)
例如:
hello.orange.rabbit 匹配Q1,Q2
lazy.orange 匹配Q2
(1)producer生产者代码
public class ProducerTest {
public static void main(String[] args) throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//创建队列
/**
* String queue, 队列名称
* boolean durable, 是否持久化
* boolean exclusive, 是否独占的,,即只允许一个 设为false
* boolean autoDelete, 是否自动删除 ,如果长时间没有发生消息,自动删除
* Map<String, Object> arguments 额外参数
* */
channel.queueDeclare("ban_queue_topic01",true,false,true,null);
channel.queueDeclare("ban_queue_topic02",true,false,true,null);
//创建交换机
//String exchange, String type, boolean durable
channel.exchangeDeclare("ban_exchange_topic", BuiltinExchangeType.TOPIC,true);
//绑定队列
//String queue, String exchange, String routingKey
channel.queueBind("ban_queue_topic01","ban_exchange_topic","*.orange.*");
channel.queueBind("ban_queue_topic02","ban_exchange_topic","*.*.rabbit");
channel.queueBind("ban_queue_topic02","ban_exchange_topic","lazy.#");
//产生消息
/**
* String exchange, 交换机的名称 使用默认的则填""
* String routingKey, 路由的key,如果没有交换机的绑定,则填队列的名称
* BasicProperties props, 消息的额外配置 ,没有填null
* byte[] body 参数,即消息的内容
* */
// String ss="杨可真是美若天仙了,不愧是舒隆振的老婆!";
for (int i = 0; i < 10; i++) {
String ss="从前有座山"+i;
channel.basicPublish("ban_exchange_topic","lazy.orange.rabbit",null,ss.getBytes());
}
}
}
(2)consumer消费者01代码
public class ConnectionTest01 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_topic01",true,callback);
}
}
(3)consumer消费者02代码
public class ConnectionTest02 {
public static void main(String[] args)throws Exception {
//创建rebitt工厂,并添加条件
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.31.168");
//创建连接对象
Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//获取消息
/**
* (String queue, 队列的名称
* boolean autoAck, 是否自动确认
* Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
* */
DefaultConsumer callback = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//body接收的消息
System.out.println("消息的内容为:------》"+new String(body));
}
};
channel.basicConsume("ban_queue_topic02",true,callback);
}
}