一、Springboot整合RabbitMQ
1.1 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
1.2 application.yml
rabbitmq: host: 192.168.31.128 port: 5672 username: mqroot password: mqroot virtual-host: test # 消息确认类型 NONE 默认值 禁止发布调用模式 correlated 发布消息成功到交换器后会触发回调方 法 publisher-confirm-type: correlated # 设置允许消息从交换机路由到队列失败时的回调 默认值是false 即不执行回调 publisher-returns: true listener: direct: # 手动ack 默认值是auto 自动确认 manual 是手动确认 acknowledge-mode: manual
1.3 rabbitmq配置类
Queue参数信息
-
name: 队列的名称;
-
actualName: 队列的真实名称,默认用name参数,如果name为空,则根据规则生成一个;
-
durable: 是否持久化;
-
exclusive: 是否独享、排外的;
-
autoDelete: 是否自动删除;
-
arguments:队列的其他属性参数,有如下可选项,可参看图2的arguments:
-
x-message-ttl:消息的过期时间,单位:毫秒;
-
x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
-
x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
-
x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
-
x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
-
x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
-
x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
-
x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
-
x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
-
x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
-
x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。
-
交换机参数信息
类型
-
FanoutExchange :扇形 交换机
-
DirectExchange :直连交换机 routing模式用的交换机
-
TopicExchange :主题模式交换机
参数信息
-
name:交换机名称
-
durable:是否把交换机持久化到磁盘上
-
autoDelete :是否自动删除交换机 用法有点类似上面的队列中的autoDelete 只有所有队列都和交换机接触订阅,说白了就是所有绑定到交换机上的队列不再需要改交换机,他就该死了,有点残酷
-
artuments :额外参数
配置类
@Configuration
public class RabbitMQConfig {
public static final String EX_CHANGE = "ex.direct";
public static final String ORDER_QUEUE = "order.queue";
public static final String ORDER_QUEUE_KEY = "order";
public static final String DLL_ORDER_QUEUE = "ddl.order.queue";
public static final String DLL_ORDER_QUEUE_KEY = "ddl.order";
@Bean("exDirect")
public DirectExchange initExchange() {
// new FanoutExchange()
return new DirectExchange(EX_CHANGE, true, false);
}
@Bean("orderQueue")
public Queue initOrderQueue() {
// 设置有效期
HashMap<String, Object> map = new HashMap<>();
map.put("x-message-ttl",10000);
map.put("x-dead-letter-exchange",EX_CHANGE);
map.put("x-dead-letter-routing-key",DLL_ORDER_QUEUE_KEY);
map.put("x-overflow","reject-publish");
return new Queue(ORDER_QUEUE,true);
}
@Bean("ddlOrderQueue")
public Queue initDDLOrderQueue() {
return new Queue(DLL_ORDER_QUEUE,true);
}
// 绑定
@Bean("bindingQueue")
public Binding bindingQueue(@Qualifier("orderQueue") Queue queue,@Qualifier("exDirect") DirectExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ORDER_QUEUE_KEY);
}
@Bean("bindingDDLQueue")
public Binding bindingDDLQueue(@Qualifier("ddlOrderQueue") Queue queue,@Qualifier("exDirect") DirectExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(DLL_ORDER_QUEUE_KEY);
}
/*
---------------------------------------
--------------其他类型交换机配置类似-------
---------------------------------------
*/
/**
* 将队列和交换机绑定, 并设置用于匹配键
* @return
*/
@Bean
public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
/*
ConfirmCallback是用来得知是否进入到交换机
ReturnCallback是获取未进入队列的回调信息,如果成功进入队列,不会进入这个回调方法。必须设置rabbitTemplate.setMandatory(true);
*/
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
// 消息进入到MQ触发,是否到交换机
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("ConfirmCallback:相关数据:" + correlationData);
System.out.println("ConfirmCallback:确认情况:" + ack);
System.out.println("ConfirmCallback:原因:" + cause);
}
});
// 设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
// 为true时,消息通过交换器无法匹配到队列会返回给生产者,并触发MessageReturn,为false时,匹配不到会直接被丢弃
rabbitTemplate.setMandatory(true);
// 消息未进入队列时触发回调
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("ReturnCallback:消息:" + message);
System.out.println("ReturnCallback:回应码:" + replyCode);
System.out.println("ReturnCallback:回应信息:" + replyText);
System.out.println("ReturnCallback:交换机:" + exchange);
System.out.println("ReturnCallback:路由键:" + routingKey);
}
});
return rabbitTemplate;
}
}
1.4 生产者
@RestController
public class RabbitMQProductController {
@Resource
RabbitTemplate rabbitTemplate;
@PostMapping("send")
public String send() {
String messageId = String.valueOf(UUID.randomUUID());
String messageData = "test message, hello!";
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String, Object> map = new HashMap<>();
map.put("messageId", messageId);
map.put("messageData", messageData);
map.put("createTime", createTime);
//将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange
rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
return "ok";
}
}
1.5 消费者
@RabbitListener添加给类
@Component
@RabbitListener(queues = "TestDirectQueue")//监听的队列名称 TestDirectQueue
public class DirectReceiver {
@RabbitHandler
public void process(Map testMessage, Message message, Channel channel) throws IOException {
System.out.println("DirectReceiver消费者收到消息 : " + testMessage.toString());
System.out.println(message);
// 手动应答
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
}
@RabbitListener添加给方法
/**
* 消费者:监听队列,从队列中获取消息,并处理消息
*/
@Component
public class DirectListener2 {
/**
*
* @param msg:获取到的消息,类型与发布时的类型一致
* @param message:消息的详细信息:消息内容body,存储信息(队列,交换机,路由,标识符)
* @param channel:信道
*/
@RabbitListener(queues = RabbitMQConfig.DIRECT_EXCHANGE_QUEUE)
public void handleMyQueue(Map msg, Message message, Channel channel) throws IOException {
System.out.println("队列my-queue的信息");
System.out.println(msg.toString());
System.out.println(message);
System.out.println(channel);
// 手动应答
channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
}
@RabbitListener(queues = "aaa")
public void handleAAA(String msg, Message message, Channel channel) throws IOException {
System.out.println("队列aaa的信息");
System.out.println(msg.toString());
System.out.println(message);
System.out.println(channel);
// 手动应答
channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
}
}
50万+

被折叠的 条评论
为什么被折叠?



