文章目录
八、SpringBoot 整合RabbitMQ
1.pom.xml
添加AMQP的启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置
server:
port: 8088
spring:
application:
name: mq-rabbitmq-producer
rabbitmq:
host: xxxx
port: 5672
username: xxxx
password: xxxx
virtualHost: /
template:
retry:
enabled: true
initial-interval: 10000ms
max-interval: 300000ms
multiplier: 2
exchange: topic.exchange
publisher-confirms: true
-
template:有关AmqpTemplate的配置
-
retry:失败重试
-
enabled:开启失败重试
-
initial-interval:第一次重试的间隔时长
-
max-interval:最长重试间隔,超过这个间隔将不再重试
-
multiplier:下次重试间隔的倍数,此处是2即下次重试间隔是上次的2倍
-
-
exchange:交换机名称,此处配置后,发送消息如果不指定交换机就会使用这个
-
-
publisher-confirms:生产者确认机制,确保消息会正确发送,如果发送失败会有错误回执,从而触发重试
3.配置类config
package com.merist.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
@Configuration
public class RabbitMQConfig {
public static final String QUEUE_ERROR = "queue_error";
public static final String QUEUE_LOG = "queue_log";
public static final String EXCHANGE_NAME = "topic.exchange";
public static final String ROUTINGKEY_ERROR = "topic.#.error.#";
public static final String ROUTINGKEY_LOG = "topic.#.log.#";
//声明交换机
@Bean(EXCHANGE_NAME)
public Exchange exchange(){
return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
}
//声明error队列
//参数:String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
/**
* 参数明细
* 1、queue 队列名称
* 2、durable 是否持久化,如果持久化,mq重启后队列还在
* 3、exclusive 是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
* 4、autoDelete 自动删除,队列不再使用时是否自动删除此队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除)
* 5、arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间
*/
@Bean(QUEUE_ERROR)
public Queue errorQueue(){
return new Queue(QUEUE_ERROR);
}
//声明log队列
@Bean(QUEUE_LOG)
public Queue logQueue(){
return new Queue(QUEUE_LOG);
}
//error队列绑定交换机指定RoutingKey
@Bean
public Binding bindingError(@Qualifier(QUEUE_ERROR) Queue queue,
@Qualifier(EXCHANGE_NAME) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_ERROR).noargs();
}
//log队列绑定交换机指定RoutingKey
@Bean
public Binding bindingLog(@Qualifier(QUEUE_LOG) Queue queue,
@Qualifier(EXCHANGE_NAME) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_LOG).noargs();
}
}
4.生产者
@SpringBootTest
public class Send {
@Autowired
RabbitTemplate rabbitTemplate;
@Test
public void sedMsgByTopics(){
/**
* 参数:
* 1、交换机名称
* 2、routingKey
* 3、消息内容
*/
for (int i=0;i<5;i++){
String message = "login ERROR!["+i+"]";
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"topic.log.error",message);
System.out.println(" [生产者] Sent '" + message + "'");
}
}
}
5.消费者
新建一个消费者工程,添加配置文件application.yml
server:
port: 8089
spring:
application:
name: mq-rabbitmq-consumer
rabbitmq:
host: xxxx
port: 5672
username: xxxx
password: xxxx
virtualHost: /
template:
retry:
enabled: true
initial-interval: 10000ms
max-interval: 300000ms
multiplier: 2
exchange: topic.exchange
publisher-confirms: true
-
@Componet:类上的注解,注册到Spring容器
-
@RabbitListener:方法上的注解,声明这个方法是一个消费者方法,需要指定下面的属性:
-
bindings:指定绑定关系,可以有多个。值是@QueueBinding的数组。@QueueBinding包含下面属性:
-
value:这个消费者关联的队列。值是@Queue,代表一个队列
-
exchange:队列所绑定的交换机,值是@Exchange类型
-
key:队列和交换机绑定的RoutingKey,可指定多个
-
-
@Component
public class ReceiveHandler {
//监听error队列
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue_error",durable = "true"),
exchange = @Exchange(
value = "topic.exchange",
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {"topic.#.error.#","error.#"}))
public void rece_error(String msg){
System.out.println("[error]:"+msg+"!");
}
//监听error队列
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue_log",durable = "true"),
exchange = @Exchange(
value = "topic.exchange",
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {"topic.#.log.#","log.#"}))
public void rece_log(String msg){
System.out.println("[log]:"+msg+"!");
}
}
启动:
九、SpringBoot中RabbitMQ的基本使用
1.RabbitAtuoConfiguration配置类
引入 AMQP 场景, RabbitAutoConfiguration 自动生效
给容器中自动配置了:
- RabbitTemplate
- AmqpAdmin
- CachingConnectionFactory
- RabbitMessageingTemplate
2.RabbitTemplate
- 发送消息
send()、convertAndSend()将发送的对象转化为字节流数据
@Bean
@ConditionalOnSingleCandidate(ConnectionFactory.class)
@ConditionalOnMissingBean({RabbitOperations.class})
public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate();
configurer.configure(template, connectionFactory);
return template;
}
3.AmqpAdmin
- 声明交换机
declareExchange()
- 创建队列
delcareQueue()
@Bean
@ConditionalOnSingleCandidate(ConnectionFactory.class)
@ConditionalOnProperty(
prefix = "spring.rabbitmq",
name = {"dynamic"},
matchIfMissing = true
)
@ConditionalOnMissingBean
public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
交换机类的参数:
4.RabbitMessagingTemplate
配置消息传递时的序列化方式
在RedisTemplate的配置类中会配置。
在 java 中一般使用 Json 序列化:
@Configuration
public class MyRabbitConfig {
/**
* 配置rabbitmq的对象消息序列化机制为json
* @return
*/
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
5.监听队列消息注解
@RabbitListener
、@RabbitHandler
:
@RabbitListener
该注解可以写在类、方法上面,用于绑定队列@RabbitHandler
只能标注方法上,可以用于方法重载区分收到的不同信息- 原生方式获取消息内容:使用
Message message
(类似ResponseBody
自动获取),然后在message.getBody()
获取Object
然后一系列转化。 - 快捷的方式:直接使用 对应实体类 来映射获取数据
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue_error",durable = "true"),
exchange = @Exchange(
value = "topic.exchange",
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {"topic.#.error.#","error.#"}))
public void rece_error(String msg){
System.out.println("[error]:"+msg+"!");
}