Spring Boot集成Rabbit MQ实战

一、Rabbit MQ简介

Rabbit MQ是基于Erlang语言开发的消息队列中间件系统,主要用来解决数据实时同步和响应问题。消息中间件产品比较常见的有ActiveMQ、Kafka、Rabbit MQ、RocketMQ等等。Rabbit MQ的优势是通过交换机绑定队列,消息支持持久化,服务器宕机消息仍然存在。并且Rabbit MQ支持ACK确认机制,消费确认,也支持分布式事务。

二、应用场景

Rabbit MQ支持多种语言客户端,比如C、Ruby、Java、Python、C#、PHP等主流语言。笔者曾经做过消息中转推送中心,基于Rabbit MQ的一个二次开发,将微信推送消息、短信平台、语音消息、邮件等消息推送封装在消息中心,通过Rabbit MQ开放接口,其他系统只需要按照接口协议封装实体类发送JSON数据,消息中心就能推送微信、短信、语音、邮件给用户,并且具有重试机制,不成功的消息记录到消息日志表中。

三、主要组件

虚拟主机:RabbitMQ支持权限控制,但是最小控制粒度为虚拟主机。一个虚拟主机可以包含多个交换机、队列、绑定。

交换机:交换机用来绑定队列,用于消息中间权限控制。

队列:队列用来存放消息,原理基于数据结构里面的队列。

然后通过将交换机和队列绑定在一起从而组成消息广播、消息存储与发送。

四、Spring Boot与Rabbit MQ整合搭建

新建一个Maven工程,与Spring Boot整合的Rabbit MQ在pom.xml中的配置为:

org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-amqp org.springframework.boot spring-boot-starter-test test

在src/main/resources目录下新建application.yml指定项目端口号与连接Rabbit MQ配置,如下:

#访问端口server: port: 8482spring: application: name: ocai-core-rabbitmq session: store-type: none rabbitmq: host: 127.0.0.1 port: 5672 username: guest password: guest

新建com.ocai.core.mq.model包,在该包下新建实体User,代码为:




JAVA rabbitmq接收推送消息_rabbitmq实战


新建com.hxdi.core.mq.rabbit包,包下新建RabbitConfig.java进行绑定队列,注意注解@Configuration


JAVA rabbitmq接收推送消息_rabbitmq工具类_02


新建com.ocai.core.mq.rabbit.hello包,包下新建消息发送Bean组件,如图


JAVA rabbitmq接收推送消息_rabbitmq实战_03


建立队列监听者,@RabbitListener(queues = "hello")表示监听hello这个队列


JAVA rabbitmq接收推送消息_rabbitmq实战_04


新建Junit测试工具类,通过调用HelloSender发送消息,如图


JAVA rabbitmq接收推送消息_rabbitmq实战_05


右键HelloTest运行测试工具,查看控制台结果


JAVA rabbitmq接收推送消息_rabbitmq工具类_06


结果Sender为发送消息,Receiver为接收消息。

五、发送对象消息

新建ObjectSender,消息发送者,如图


JAVA rabbitmq接收推送消息_rabbitmq实战_07


新建ObjectReceiver绑定队列queues = "object"监听器,接收消息


JAVA rabbitmq接收推送消息_rabbitmq工具类_08


新建Junit Test


JAVA rabbitmq接收推送消息_rabbitmq工具类_09


运行之后查看控制台


JAVA rabbitmq接收推送消息_rabbitmq实战_10


接收对象

六、建立Topic交换机队列

建立TopicRabbitConfig.java,建立队列


JAVA rabbitmq接收推送消息_rabbitmq工具类_11


建立交换机


JAVA rabbitmq接收推送消息_rabbitmq工具类_12


绑定交换机与队列并指定路由键


JAVA rabbitmq接收推送消息_rabbitmq实战_13


指定队列Sender,匹配topic.#路由键,并指定交换机topicExchange


JAVA rabbitmq接收推送消息_rabbitmq实战_14


匹配topic.message路由键


JAVA rabbitmq接收推送消息_rabbitmq实战_15


匹配topic.#路由键


JAVA rabbitmq接收推送消息_rabbitmq实战_16


接收队列queues = "topic.message"


JAVA rabbitmq接收推送消息_rabbitmq工具类_17


接收队列queues = "topic.messages"


JAVA rabbitmq接收推送消息_rabbitmq工具类_18


建立Junit,代码如下:


JAVA rabbitmq接收推送消息_rabbitmq工具类_19


运行topic查看队列接收情况


JAVA rabbitmq接收推送消息_rabbitmq实战_20


由于绑定关系


JAVA rabbitmq接收推送消息_rabbitmq工具类_21


因此是topic.messages这个队列接收到消息


JAVA rabbitmq接收推送消息_rabbitmq工具类_22


回到Junit运行


JAVA rabbitmq接收推送消息_rabbitmq工具类_23


运行结果


JAVA rabbitmq接收推送消息_rabbitmq实战_24


可以看到queues = "topic.message"和queues = "topic.messages"这2个队列都收到了消息。

因为绑定关系


JAVA rabbitmq接收推送消息_rabbitmq工具类_25


而发送者


JAVA rabbitmq接收推送消息_rabbitmq实战_26


对于这2个路由键都符合

返回Junit运行


JAVA rabbitmq接收推送消息_rabbitmq工具类_27


运行结果


JAVA rabbitmq接收推送消息_rabbitmq工具类_28


因为发送者


JAVA rabbitmq接收推送消息_rabbitmq实战_29


topic.messages只匹配


JAVA rabbitmq接收推送消息_rabbitmq实战_30


这个路由键,也就是


JAVA rabbitmq接收推送消息_rabbitmq实战_31


这个队列

七、Fanout广播

广播FanoutRabbitConfig代码如下:

import org.springframework.amqp.core.Binding;import org.springframework.amqp.core.BindingBuilder;import org.springframework.amqp.core.FanoutExchange;import org.springframework.amqp.core.Queue;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class FanoutRabbitConfig { @Bean public Queue AMessage() { return new Queue("fanout.A"); } @Bean public Queue BMessage() { return new Queue("fanout.B"); } @Bean public Queue CMessage() { return new Queue("fanout.C"); } @Bean FanoutExchange fanoutExchange() { return new FanoutExchange("fanoutExchange"); } @Bean Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) { return BindingBuilder.bind(AMessage).to(fanoutExchange); } @Bean Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) { return BindingBuilder.bind(BMessage).to(fanoutExchange); } @Bean Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) { return BindingBuilder.bind(CMessage).to(fanoutExchange); }

广播交换机fanoutExchange绑定了3个队列

队列1:


JAVA rabbitmq接收推送消息_rabbitmq工具类_32


队列2:


JAVA rabbitmq接收推送消息_rabbitmq实战_33


队列3:


JAVA rabbitmq接收推送消息_rabbitmq工具类_34


队列发送者,广播交换机:


JAVA rabbitmq接收推送消息_rabbitmq工具类_35


Junit工具如下


JAVA rabbitmq接收推送消息_rabbitmq工具类_36


运行Junit


JAVA rabbitmq接收推送消息_rabbitmq实战_37


可以看到广播交换机的3个队列都接收到了消息

八、Many队列

队列监听多次

接收者1:


JAVA rabbitmq接收推送消息_rabbitmq工具类_38


接收者2:


JAVA rabbitmq接收推送消息_rabbitmq工具类_39


发送者1:


JAVA rabbitmq接收推送消息_rabbitmq工具类_40


发送者2:


JAVA rabbitmq接收推送消息_rabbitmq工具类_41


新建Junit:


JAVA rabbitmq接收推送消息_rabbitmq实战_42


运行manyToMany


JAVA rabbitmq接收推送消息_rabbitmq实战_43


可以看到队列交错运行,同一个队列对应关系Many To Many

以上就是分享的Spring Boot集成RabbitMQ实战,有机会分享一下自己的消息中转推送中心系统。