一、引入pom文件
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
二、配置rabbitmq连接信息
spring:
rabbitmq:
host: 127.0.0.1
username: admin
password: admin
port: 5672
publisher-confirms: true
publisher-returns: true
virtual-host: ec_shop_product
listener:
simple:
#手动应答
acknowledge-mode: manual
#消费者的最小数量
concurrency: 1
#消费者的最大数量
max-concurrency: 5
#是否支持重试
retry:
enabled: true
三、通过枚举定义交换机、队列
import lombok.Getter;
@Getter
public enum OrderEnum {
ORDER_ENUM("order.direct","order.cancel","order.cancel"),
ORDER_TTL_ENUM("order.direct.ttl","order.chancel.ttl","order.chancel.ttl");
private final String exchange;
private final String name;
private final String routeKey;
OrderEnum(String exchange,String name,String routeKey){
this.exchange = exchange;
this.name = name;
this.routeKey = routeKey;
}
}
四、注入bean将交换机、对应进行绑定
package org.rabbitmq.config;
import org.rabbitmq.enums.OrderEnum;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class OrderConfig {
/**
*订单交换机
*/
@Bean
DirectExchange orderDirect(){
return (DirectExchange) ExchangeBuilder.directExchange(OrderEnum.ORDER_ENUM.getExchange()).durable(true).build();
}
/**
* 订单延时交换机
* @return
*/
@Bean
DirectExchange orderTtlDirect(){
return (DirectExchange)ExchangeBuilder.directExchange(OrderEnum.ORDER_TTL_ENUM.getExchange()).build();
}
/**
* 订单实际消费队列
*/
@Bean
public Queue orderQueue(){
return new Queue(OrderEnum.ORDER_ENUM.getName());
}
/**
* 订单延时消费队列
*/
@Bean
public Queue orderTtlQueue(){
return QueueBuilder.durable(OrderEnum.ORDER_TTL_ENUM.getName())
.withArgument("x-dead-letter-exchange",OrderEnum.ORDER_ENUM.getExchange())
.withArgument("x-dead-letter-routing-key",OrderEnum.ORDER_ENUM.getRouteKey())
.build();
}
/**
* 绑定队列到交换机
*/
@Bean
Binding orderBind(DirectExchange orderDirect,Queue orderQueue){
return BindingBuilder.bind(orderQueue).to(orderDirect).with(OrderEnum.ORDER_ENUM.getRouteKey());
}
/**
* 绑定延时队列到交换机
*/
@Bean
Binding orderTtlBind(DirectExchange orderTtlDirect,Queue orderTtlQueue){
return BindingBuilder.bind(orderTtlQueue).to(orderTtlDirect).with(OrderEnum.ORDER_TTL_ENUM.getRouteKey());
}
}
五、定义消费者处理信息
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 取消订单消息的消费者(延时处理)
* Created by macro on 2018/9/14.
*/
@Component
@RabbitListener(queues = "order.cancel")
public class CancelOrderReceiver {
private Integer stock = 10;
@RabbitHandler
public void handle(String orderId){
if(stock > 0){
stock -=1;
System.out.println("扣除库存,当前剩余库存"+stock);
}else{
System.out.println("库存不足");
}
//手动确认回复,如果长时间未返回会出现unAck情况
try {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (
IOException e) {
e.printStackTrace();
}
}
六、定义生产者
import org.rabbitmq.enums.OrderEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 取消订单消息的生产者
* Created by macro on 2018/9/14.
*/
@Component
public class CancelOrderSender {
private static final Logger logger = LoggerFactory.getLogger(CancelOrderSender.class);
@Resource
private AmqpTemplate amqpTemplate;
//延时队列
public void sendMessage(String orderId,String delayTimes){
amqpTemplate.convertAndSend(OrderEnum.ORDER_TTL_ENUM.getExchange(), OrderEnum.ORDER_TTL_ENUM.getRouteKey(), orderId, message -> {
message.getMessageProperties().setExpiration(delayTimes);
return message;
});
logger.info("send orderId:{}",orderId);
}
//普通队列
public void sendMessages(String orderId){
amqpTemplate.convertAndSend(OrderEnum.ORDER_ENUM.getExchange(), OrderEnum.ORDER_ENUM.getRouteKey(), orderId);
logger.info("send orderId:{}",orderId);
}
}