org.springframework.boot
spring-boot-starter-amqp
1、配置RabbitMq
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /
@Getter
public enum QueueEnum {
/**
* 消息通知队列
*/
QUEUE_ORDER_CANCEL("mall.order.direct", "mall.order.cancel", "mall.order.cancel"),
/**
* 消息通知ttl队列
*/
QUEUE_TTL_ORDER_CANCEL("mall.order.direct.ttl", "mall.order.cancel.ttl", "mall.order.cancel.ttl");
/**
* 交换名称
*/
private String exchange;
/**
* 队列名称
*/
private String name;
/**
* 路由键
*/
private String routeKey;
QueueEnum(String exchange, String name, String routeKey) {
this.exchange = exchange;
this.name = name;
this.routeKey = routeKey;
}
}
@Configuration
public class RabbitConfig {
@Autowired
private CachingConnectionFactory connectionFactory;
/**
* 订单消息实际消费队列所绑定的交换机
*/
@Bean
DirectExchange orderDirect() {
return (DirectExchange) ExchangeBuilder
.directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
.durable(true)
.build();
}
/**
* 订单延迟队列队列所绑定的交换机
*/
@Bean
DirectExchange orderTtlDirect() {
return (DirectExchange) ExchangeBuilder
.directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange())
.durable(true)
.build();
}
/**
* 订单实际消费队列
*/
@Bean
public Queue orderQueue() {
Map args = new HashMap<>(2);
args.put("x-dead-letter-exchange", QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange());
args.put("x-dead-letter-routing-key", QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
return QueueBuilder.durable(QueueEnum.QUEUE_ORDER_CANCEL.getName()).withArguments(args).build();
}
/**
* 订单延迟队列(死信队列)
*/
@Bean
public Queue orderTtlQueue() {
return QueueBuilder
.durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
.build();
}
/**
* 将订单队列绑定到交换机
*/
@Bean
Binding orderBinding(DirectExchange orderDirect, Queue orderQueue){
return BindingBuilder
.bind(orderQueue)
.to(orderDirect)
.with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey());
}
/**
* 将订单延迟队列绑定到交换机
*/
@Bean
Binding orderTtlBinding(DirectExchange orderTtlDirect, Queue orderTtlQueue){
return BindingBuilder
.bind(orderTtlQueue)
.to(orderTtlDirect)
.with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
}
@Bean
public RabbitTemplate rabbitTemplate() {
connectionFactory.setPublisherConfirms(true);
connectionFactory.setPublisherReturns(true);
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMandatory(true);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
return rabbitTemplate;
}
/**
* 单一消费者
*
* @return
*/
@Bean(name = "multiListenerContainer")
public SimpleRabbitListenerContainerFactory listenerContainer() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setConcurrentConsumers(1);
factory.setMaxConcurrentConsumers(1);
factory.setPrefetchCount(5);
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
return factory;
}
2、发送至队列
@Component
@Slf4j
public class CancelOrderSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void sendMessage(String orderNumber, final long delayTimes) {
// 给延迟队列发送消息
amqpTemplate.convertAndSend(QueueEnum.QUEUE_ORDER_CANCEL.getExchange(),
QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey(), orderNumber, message-> {
message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
return message;
});
log.info("send orderNumber:{}", orderNumber);
}
}
3、消费队列消息
/**
* 取消订单消息的处理者
*/
@Slf4j
@Component
@RabbitListener(queues = "mall.order.cancel.ttl", containerFactory = "multiListenerContainer")
public class CancelOrderReceiver {
@RabbitHandler
public void handle(String orderNumber, Channel channel, Message message) {
try {
//业务处理
}catch (Exception e){
try {
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}