RabbitMq 是一个消息中间件,既然是中间件,其发挥作用就必须要服务端与客户端,RabbitMQ 自身提供了服务端,我们只需要有客户端才行,有发送消息的消息生产端,接收消息的消息消费端。
RabbitMq 的功能用代码也能很简单地实现,以下使用 springboot 作为载体来快速体验消息的生产与消费。
java 代码
pom.xml 依赖
springboot 默认带的 rabbitmq 是 5.4.3
<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 http://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.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xiao</groupId>
<artifactId>rabbitmq</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rabbitmq</name>
<description>Rabbitmq project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-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>
消息生产者 MqProducer.java
在这个类中,没有另外声明交换机。如果没有声明交换机,在服务器会使用默认的 (AMQP default) 交换机,此时设置的 routingKey 必须与消费端声明的队列名保持相同,否则消息无法发送成功。
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class MqProducer {
public static void main(String[] args) throws Exception {
// 创建连接工厂,并进行属性设置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.125");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
// 第二种方式:amqp://用户名:密码@IP:端口号/虚拟主机名称 (有其他主机名称时应该能使用)
// connectionFactory.setUri("amqp://guest:guest@192.168.0.125:5672/");
// 获取连接
Connection connection = connectionFactory.newConnection();
// 创建信道
Channel channel = connection.createChannel();
// 通过信道发送信息
String msg = "hello, rabbitmq";
// channel.basicPublish(exchange, routingKey, props, body);
// 这里没有设置交换机,routingKey 必须设置成跟队列名一样,队列才能收到消息
channel.basicPublish("", "test.queue", null, msg.getBytes());
System.out.println("生产端消息:" + msg);
// 关闭连接
channel.close();
connection.close();
}
}
消息消费者 MqConsumer.java
import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
public class MqConsumer {
public static void main(String[] args) throws Exception {
// 创建连接工厂,并进行属性设置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.125");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
// 获取连接
Connection connection = connectionFactory.newConnection();
// 创建信道
Channel channel = connection.createChannel();
// 声明一个队列
String queueName = "test.queue";
// channel.queueDeclare(queue, durable, exclusive, autoDelete, arguments);
channel.queueDeclare(queueName, true, false, false, null);
// 创建消费者
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException {
String msg = new String(body, "UTF-8");
//TODO 自己的业务
//交换机
String exchange = envelope.getExchange();
//路由key
String routingKey = envelope.getRoutingKey();
//消息id
long deliveryTag = envelope.getDeliveryTag();
//消息内容
System.out.println("消费端 message : " + msg);
}
};
channel.basicConsume(queueName, true, consumer);
channel.close();
connection.close();
}
}
启动 RabbitMq 服务器
注:如果安装的 RabbitMq 不是在本地,记得在安装环境关闭防火墙或开放端口。
centos7 安装 RabbitMq
登录 RabbitMq 管控台
生产端与消费端的启动顺序
如果代码中声明的队列已经在服务端创建了,则先启动生产端较好,因为这样可以在消息消费前后去管控台看看各个服务状态的变化;
本例中的生产者代码没有使用自定义的交换机,会使用服务器默认的交换机。但是如果在发送消息时使用了自定义的交换机,则必须先运行声明交换机的一方,否则消息将发送失败。
由于上面的代码中没有使用自定义的交换机,就先启动消息生产端吧。
IDE 控制台打印了消息
在 RabbitMq 管控台中也可以看到一共一条消息,一条消息已就绪,等待消费
然后启动消费端。直接运行没有看到 IDE 打印的消息,但是用 Debug 的方式,在打印语句打个断点,可以发现语句是执行了,并且在控制台可以看到。后来发现是只要把消费端程序中关闭流的操作注释掉,正常执行就能看到打印的消息了。
RabbitMq 管控台已就绪的消息没有了
以上,就是 Rabbitmq 生产与消费消息的快速入门了