一、入门 Hello world模式
-
开发环境:
- IDEA 2020.1
- JAVA8
- RabbitMQ 3.8.3 Erlang 22.3
- Spring Boot 2.2.6
-
POM文件
<?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.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.huanlis</groupId>
<artifactId>rabbitmqtest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rabbitmqtest</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-amqp</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.9.0</version>
</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>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
一、hello world模式
Hello world模式:是RabbitMQ中的最简单的模式,生产者直连队列, 消费者也直连队列。不经过交换机。
1、创建消息发送者类 Send.java
通过连接工厂类创建工厂对象,设置来连接属性并创建连接。在连接中创建管道。通过channel.queueDeclare(QUEUE_NAME, false, false, false, null)
方法绑定管道。再通过channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
将消息发送到管道中。
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Send {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
// 创建连接mq的工厂对象
ConnectionFactory factory = new ConnectionFactory();
// 设置连接的主机地址
factory.setHost("localhost");
// 设置连接的主机端口
factory.setPort(5672);
// 设置连接的虚拟主机
factory.setVirtualHost("/ems");
// 设置访问的虚拟主机的用户和密码
factory.setUsername("root");
factory.setPassword("root");
// 创建连接
Connection connection = factory.newConnection();
// 在连接中创建管道
Channel channel = connection.createChannel();
// 通道绑定对应的消息队列
// 参数1:队列名称,如果队列不存在则自动创建
// 参数2:定义队列特性是否要持久化,true 持久化队列, false 不持久化
// 参数3:是否独占队列,true 表示只有当前的连接可以使用该队列,其他连接不可以使用该队列。 false 该队列可以被其他队列使用
// 参数4:是否在消费完成之后自动删除 false 不自动删除
// 参数5:额外的参数
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello world";
// 发布消息 通过通道绑定交换机
// 参数1: 交换机名称
// 参数2: 队列名称
// 参数3: 发布消息的额外设置
// 参数4: 发布的消息
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
for (int i=1; i< 10; i++) {
message = message + i;
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
Thread.sleep(1000);
}
// 关闭通道
channel.close();
// 关闭连接
connection.close();
}
}
2、 创建消费者类 RECV.java
与生产者相同,首先创建连接工厂对象,设置来连接属性并创建连接。在连接中创建管道。通过channel.queueDeclare()
方法绑定管道。通过channel.basicConsume();
方法来实现消息的消费。具体的细节可以看代码。需要着重强调的是这个回调方法。它是channel.basicConsume();
的第三个参数,用来实现消息的具体消费。单独使用DeliverCallback
接口来描述具体消息消费的实现是一个比较良好的模式,这个设计模式值得学习。这样就可以避免在channel.basicConsume();
的参数中写一大堆代码,既保证了代码的整洁也利于代码的维护。
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
下面是RECV.java
类的全部代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class Recv {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
// 设置连接的主机地址
factory.setHost("localhost");
// 设置连接的主机端口
factory.setPort(5672);
// 设置连接的虚拟主机
factory.setVirtualHost("/ems");
// 设置访问的虚拟主机的用户和密码
factory.setUsername("root");
factory.setPassword("root");
// 创建连接
Connection connection = factory.newConnection();
// 在连接中创建管道
Channel channel = connection.createChannel();
// 通道绑定对应的消息队列
// 参数1:队列名称,如果队列不存在则自动创建
// 参数2 durable:定义队列特性是否要持久化,true 持久化队列, false 不持久化
// 参数3 exclusive:是否独占队列,true 表示只有当前的连接可以使用该队列,其他连接不可以使用该队列。 false 该队列可以被其他队列使用
// 参数4 autoDelete:是否在消费完成之后自动删除 false 不自动删除
// 参数5 arguments:额外的参数
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
// 消费的回调函数
// 参数1 consumerTag:消费者的标签
// 参数2 delivery: 包含消息的消息体
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
// 消费信息
// 参数1:队列名称
// 参数2:autoAck: 开启消息的自动确认机制
// 参数3:消费消息的回调接口
// 参数4:取消消费的回调接口
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}
到此处已经实现了RabbitMQ的Hello world模式