在官网的教程中,描述了如上六类工作队列模式:
- 简单队列模式:最简单的工作队列,其中一个消息生产者,一个消息消费者,一个队列。也称为点对点模式。
- 工作模式:一个消息生产者,一个交换器,一个消息队列,多个消费者,同样也称为点对点模式。
- 发布/订阅模式:无选择接收消息,一个消息生产者,一个交换器,多个消息队列,多个消费者。称为发布/订阅模式。
- 路由模式:在发布/订阅模式的基础上,有选择的接收消息,也就是通过 routing 路由进行匹配条件是否满足接收消息。
- 主题模式:同样是在发布/订阅模式的基础上,根据主题匹配进行筛选是否接收消息,比第四类更灵活。
- RPC模式:与上面其他5种所不同之处,类模式是拥有请求/回复的。也就是有响应的,上面5种都没有。
接下来几篇文章一起来讨论这几种队列模式吧,本篇为简单队列模式。
目录
1、实现功能
功能描述:一个生产者 P 发送消息到队列 Q,一个消费者 C 接收
P 表示为生产者 、C 表示为消费者,红色表示队列。
2、构建项目
创建一个简单的springboot+maven项目
- rabbitmq 父工程
-- common 存放公用工具类
-- customer 消费者
-- producer生产者
2.1 导入依赖
在 rabbitmq 父工程 pom.xml 导入 maven 依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>
2.2 封装Connection
common模块中封装 rabbitmq 连接类
package com.shuofeng.common;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class MQConnectionUtils {
public static Connection newConnection() throws IOException, TimeoutException{
//1.定义链接工厂
ConnectionFactory factory = new ConnectionFactory();
//2.设置服务器地址
factory.setHost("127.0.0.1");
//3.设置端口号
factory.setPort(5672);
//4.设置vhost
factory.setVirtualHost("test001_host");
//5.设置用户名称
factory.setUsername("guest");
//6.设置用户密码
factory.setPassword("guest");
//7.创建新的连接
Connection newConnection = factory.newConnection();
return newConnection;
}
}
3、生产者
生产者负责创建消息队列并发送消息入列,简单分为5步:
- 获取连接
- 创建通道
- 创建队列声明
- 发送消息
- 关闭队列
package com.shuofeng.producer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shuofeng.common.MQConnectionUtils;
public class Producer {
//队列名称
private static final String QUEUE_NAME = "test001_queue";
public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection newConnection = MQConnectionUtils.newConnection();
//2.创建通道
Channel channel = newConnection.createChannel();
//3.创建队列声明
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.发送消息
String msg = "我是生产者生成的消息001";
System.out.println("生产者发送消息:" + msg);
channel.basicPublish("",QUEUE_NAME, null, msg.getBytes());
//5.关闭队列
channel.close();
newConnection.close();
}
}
4、消费者
消费者实现和生产者实现过程差不多,但是没有关闭连接和通道,是因为要消费者一直等待随时可能发来的消息,
大致分为如下3步:
- 获取连接
- 获取通道
- 监听队列
package com.shuofeng.customer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.shuofeng.common.MQConnectionUtils;
public class Customer {
//队列名称
private static final String QUEUE_NAME = "test001_queue";
public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection newConnection = MQConnectionUtils.newConnection();
//2.获取通道
Channel channel = newConnection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msgString = new String(body, "UTF-8");
System.out.println("消费者获取消息:" + msgString);
}
};
//3.获取监听
channel.basicConsume(QUEUE_NAME, true,defaultConsumer);
}
}
5、测试环节
至此,整个项目代码写完了,接下来就是测试环节
5.1 启动RabbitMQ
5.2 创建vhost
5.3 依次运行Producer\Customer
Producer生产者启动 发送3条消息
Customer消费者启动 收到3条消息
6、总结
简单队列虽然简单,但是有一些不足,比如这种点对点无疑在复杂情况下会产生大量冗余代码。