最近工作太忙,每天回到家都10点多,11点多,都没精力学习了,没精力写博客,后面希望能好一点,能抽出一些时间来自我提升。就决定从rabbitmq开始,系统学习一波。
RabbitMQ快速开始,通过原生API快速创建自己第一个demo,实现消息的生产和消费
1. 快速创建一个工程并引入相关依赖
tips:我这边是直接创建一个springboot工程,因为idea创建一个springboot工程十分方便
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.vivo</groupId>
<artifactId>demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--尽量安装的MQ和使用的rabbitmq客户端依赖版本统一,防止意外的幺蛾子-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2. 编写生产者代码
package com.vivo.demo1.quickstart;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author:luzaichun
* @Date:2020/12/13
* @Time:14:43
**/
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.3.6");
factory.setPort(5672);
factory.setVirtualHost("/");
//2.通过工厂创建链接
Connection connection = factory.newConnection();
//3.通过连接获取channel
Channel channel = connection.createChannel();
//4.channel做消息发送
byte[] msgBody = "快速开始第一条消息发送".getBytes();
channel.basicPublish("quick_exchange","quick",null,msgBody);
//5.关闭资源
channel.close();
connection.close();
}
}
channel.basicPublish()方法参数讲解:
- exchange:指定要将消息发送到那个交换机 (如果不指定exchange,会使用默认的exchange; 并且需要有一个队列名等于routingKey的队列,消息才能路由成功)
- routingKey:设置改消息的路由key,决定该消息路由到与交换机绑定的那个队列上(一个交换机可能绑定了多个队列)
- props:消息参数设置。例如消息的TTL等,这里暂时不设置(用该对象设置 AMQP.BasicProperties)
- msgBody;发送的消息
3. 编写消费者端代码
package com.vivo.demo1.quickstart;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author:luzaichun
* @Date:2020/12/13
* @Time:14:53
**/
@Slf4j
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.3.6");
factory.setPort(5672);
factory.setVirtualHost("/");
//2.创建连接
Connection connection = factory.newConnection();
//3.创建channel
Channel channel = connection.createChannel();
//4.声明队列,交换机,并绑定
/**
* queue:队列名称
* durabel:队列是否持久化(队列在重启后是否恢复)
* exclusive:独占方式消费,这个队列只能被一个consumer连接使用,顺序消费需要
* autoDelete:这个队列如果脱离了exchange会被删除。
* arguments:扩展参数
*/
channel.queueDeclare("quick_queue", false, false, false, null);
/**
* exchange:交换机的名称
* type:交换机类型 例如:topic、direct、fanout
* durable:交换机是否持久化,重启后是否能恢复
*/
channel.exchangeDeclare("quick_exchange","topic",false);
/**
* queue:需要进行绑定的队列名
* exchange:需要进行绑定的交换机名
* routingKey:交换机和队列之间的路由规则
*/
channel.queueBind("quick_queue","quick_exchange","quick");
//5.声明consumer
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume("quick_queue", true, consumer);
//6.获取消息
while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
byte[] body = delivery.getBody();
log.info("消费者接收到消息:{}",new String(body));
}
}
}
- channel.queueDeclare()和channel.exchangeDeclare()方法参数durabel参数都设置为了false,所以在MQ的server重启后,你会发现我们声明的quick_queue、quick_exchange都消失了(可以通过mq管控台观察)
- 你也可以将参数设置为durabel参数都设置为true,然后重启MQ的server,再观察下,是否可以持久化queue和exchange
- 建议先测试非持久化的,再测试持久化的,不然你还得手动删除持久化的queue和exchange
- 测试
我们先启动consumer端,然后通过管控台检查,看queue、exchange是否都没有问题,以及绑定关系
队列和交换机的声明都没问题,我们再检查下绑定关系
通过点击队列名称或者交换机名称,查看详细信息
确认都没有问题后,启动生产者发送消息。关查消费者是否能接收到消息
可以看到,生产者发送了一条消息,消费者能消费到这条消息,通过管控台的监控对比也可以看到,在14:01分有一条消息产生,并被消费。
好了,第一个RabbitMQ的demo就到这里结束。