目录
1.RabbitMQ介绍
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。支持Windows、Linux/Unix、MAC OS X操作系统和包括JAVA在内的多种编程语言。
2.RabbitMQ的工作原理
RabbitMQ的基本结构:
组成部分说明:
Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的
Producer:消息生产者,即生产方客户端,生产方客户端将消息发送
Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
生产者发送消息流程:
1.生产者和Broker建立TCP连接。
2.生产者和Broker建立通道。
3.生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4.Exchange将消息转发到指定的Queue(队列)
消费者接收消息流程:
1.消费者和Broker建立TCP连接
2.消费者和Broker建立通道
3.消费者监听指定的Queue(队列)
4.当有消息到达Queue时Broker默认将消息推送给消费者。
5.消费者接收到消息。
6.ack回复
3. SpringBoot 整合实现RabbitMQ
创建2个springboot项目,一个 mq-rabbitmq-producer(生产者),一个mq-rabbitmq-consumer(消费者)。
3.1创建mq-rabbitmq-producer(生产者)发送消息
3.1.1pom.xml中添加相关的依赖:
<!--添加AMQP的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.1.2 配置application.yml
server:
port: 8080
spring:
application:
name: mq-rabbitmq-producer
#rabbitmq配置
rabbitmq:
host: localhost
port: 5672
#注意:guest用户只能链接本地服务器 比如localhost 不可以连接远程服务器
username: guest
password: guest
#虚拟主机 一台机器可能有很多虚拟主机 这里选择默认配置 / 即可
virtual-host: /
#支持发布返回
publisher-returns: true
listener:
# Routing 路由模型(交换机类型:direct)
direct:
#消息确认:手动签收
acknowledge-mode: manual
#当前监听容器数
concurrency: 1
#最大数
max-concurrency: 10
#是否支持重试
retry:
enabled: true
#重试次数5,超过5次抛出异常
max-attempts: 5
#重试间隔 3s
max-interval: 3000
采用 Routing 路由模型(交换机类型:direct)方式
,实现RabbitMQ消息队列。
3.1.3 配置RabbitMQ常量类
配置直连交换机名称、消息队列名称、routingkey
package com.example.mqrabbitmqproducer.util.rabbitmq;
/**
* RabbitMQ RoutingKey 常量工具类
* @author qzz
*/
public class RabbitMQConstantUtil {
/**
* 交换机名称
*/
public static final String DIRECT_EXCHANGE = "directExchange";
/**
* 取消订单 队列名称 \routingkey
*/
public static final String CANCEL_ORDER = "cancel-order";
/**
* 自动确认订单 队列名称\routingkey
*/
public static final String CONFIRM_ORDER = "confirm-order";
}
注意:我这里把消息队列名称和routingkey设置为同名。
3.1.4 创建RabbitMQConfig配置类
rabbitmq配置类:配置Exchange、Queue、以及绑定交换机
package com.example.mqrabbitmqproducer.util.rabbitmq.config;
import com.example.mqrabbitmqproducer.util.rabbitmq.RabbitMQConstantUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* rabbitmq配置类:配置Exchange、Queue、以及绑定交换机
* @author qzz
*/
@Configuration
@EnableRabbit
public class RabbitMQConfig {
private static final Logger log = LoggerFactory.getLogger(RabbitMQConfig.class);
@Autowired
private RabbitTemplate rabbitTemplate;
@Bean
public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
//SimpleRabbitListenerContainerFactory发现消息中有content_type有text就会默认将其转换成string类型的
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
/**
* 比较常用的 Converter 就是 Jackson2JsonMessageConverter,在发送消息时,它会先将自定义的消息类序列化成json格式,
* 再转成byte构造 Message,在接收消息时,会将接收到的 Message 再反序列化成自定义的类
*/
factory.setMessageConverter(new Jackson2JsonMessageConverter());
//开启手动ACK
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}
@Bean
public AmqpTemplate amqpTemplate(){
rabbitTemplate.setEncoding("UTF-8");
rabbitTemplate.setMandatory(true);