一、RabbitMq基础知识
0、概述
消息队列的作用就是接收消息生产者的消息,然后将消息发送到消费者
1、信道channel
我的理解是生产者/消费者和rabbitmq交互的一个通道,负责交换机、队列管理;消息发布和消费管理;事务管理等
2、交换机
四种交换机:
direct:可以用一个或者多个key绑定到一个或者多个队列上
topic:支持路由的适配符 # *
Fanout广播:将消息发送给所有的队列
Header头交换机:自定义通过头消息属性来定义路由的匹配
3、队列:保存消息的队列
4、消费者:消息的接收者
5、生产者:消息的发送者
二、 使用com.rabbitmq.client.*
操作mq
2.1、基本操作
0、环境和依赖
<!-- 环境
* jdk 1.8
* idea
* springboot 2.2.6
-->
<!-- 依赖 这里只导入这个包,其中包含了Rabbit client的包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
1、创建连接和信道
//获取连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");//mq主机地址
factory.setPort(5672);//端口,默认时5672
factory.setUsername("leyou");
factory.setPassword("leyou");
factory.setVirtualHost("/leyou");
Connection connection = factory.newConnection();
//获取信道
Channel channel = connection..createChannel();
2、申明交换机 / 队列 / 绑定交换机和队列
//交换机名,交换机类型
channel.exchangeDeclare(EXCHANGE, BuiltinExchangeType.DIRECT);
/**
* 第一个参数是queue:要创建的队列名
* 第二个参数是durable:是否持久化。如果为true,可以在RabbitMQ崩溃后恢复消息
* 第三个参数是exclusive:true表示一个队列只能被一个消费者占有并消费
* 第四个参数是autoDelete:true表示服务器不在使用这个队列是会自动删除它
* 第五个参数是arguments:包括死信队列,队列的ttl
*/
channel.queueDeclare(QUEUE_ONE,true,false,false,null);
//绑定交换机和队列 队列名,交换机名,routekey
channel.queueBind(QUEUE_ONE,EXCHANGE,GIRL);
3、发布消息
//1、交换机名 2、routekey 3、mandatory强制(需要return回调时必须设置为true) 4、发布消息参数 5、消息
channel.basicPublish(EXCHANGE,GIRL,true,null,"xxx降价了".getBytes());
4、接收消息
//接收消息前也需要获取连接和channel,申明队列
//接收消息
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//拿到消息
System.out.println(new String(body,"utf-8"));
}
};
/**
* 参数说明
* 1:队列名字
* 2:是否自动应答 autoACk,为false时需要手动ack
* 3:消费者,当接收到消费者时会调用给对象中的 handleDelivery 方法
*/
channel.basicConsume(QUEUE_ONE,true,consumer);
2.2、基本应用
1、功能:
有两个人小明和小华,小明对美女感兴趣,小华对股票和没事感兴趣,使用消息队列将他们感兴趣的消息发送给他们两个
2、实现:
(1)写一个类来提供创建连接和信道;
(2)生产者(发送消息方)类发送消息
(3)消费者(接收消息)类接收消息
- 连接类
public class ConnectionUtil {
/**
* 使用原始的rabbitmq client api 操作mq
*/
private static ConnectionFactory factory = new ConnectionFactory();
private static Connection connection;
/*
获取连接
注意导包:需要导client下面的包
*/
public static Connection getConnection() throws IOException, TimeoutException {
// factory.setHost("localhost");
// factory.setPort(5672);
factory.setUsername("leyou");
factory.setPassword("leyou");
factory.setVirtualHost("/leyou");
connection = factory.newConnection();
return connection;
}
public static void close() throws IOException {
connection.close();
}
/*
创建信道
*/
public static Channel getChannel() throws IOException, TimeoutException {
return getConnection().createChannel();
}
}
- 生产者
//生产者
public class provice{
public void producerMsg() throws IOException, TimeoutException, InterruptedException {
Channel channel = ConnectionUtil.getChannel();
String EXCHANGE = "direct_exchange";
channel.exchangeDeclare(EXCHANGE, BuiltinExchangeType.DIRECT);
//定义两个队列名
String QUEUE_ONE = "beauty_queue";
String QUEUE_TWO = "food_queue";
channel.queueDeclare(QUEUE_ONE,true,false,false,null);
channel.queueDeclare(QUEUE_TWO,tru