https://blog.csdn.net/hellozpc/article/details/81436980
公司的配置
spring.rabbitmq.host=192.168.100.222,192.168.100.220,192.168.100.144
spring.rabbitmq.port=5672
spring.rabbitmq.connection-timeout=50000
spring.rabbitmq.template.receive-timeout=5000
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.listener.simple.concurrency=4
spring.rabbitmq.listener.simple.max-concurrency=8
spring.rabbitmq.listener.simple.retry.enabled=true
#RabbitMQ\u7684\u865A\u62DFhost
spring.rabbitmq.virtual-host=/
# \u624B\u52A8ACK \u4E0D\u5F00\u542F\u81EA\u52A8ACK\u6A21\u5F0F,\u76EE\u7684\u662F\u9632\u6B62\u62A5\u9519\u540E\u672A\u6B63\u786E\u5904\u7406\u6D88\u606F\u4E22\u5931 \u9ED8\u8BA4 \u4E3A none
spring.rabbitmq.listener.simple.acknowledge-mode=manual
package com.wt.console.base.config;
import com.wt.journey.enums.ExchangeEnum;
import com.wt.journey.enums.QueueEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author liufan
* @version 1.0
* @date 2019/11/27 15:51
*/
@Component
public class RabbitMQConfig {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// @Bean
// @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
// 消息发送失败返回到队列中, yml需要配置 publisher-returns: true
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMandatory(true);
template.setReturnCallback((message,replyCode,replyText,exchange,routingKey)->{
String correlationId = Arrays.toString(message.getMessageProperties().getCorrelationId());
logger.error("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {} 路由键: {}", correlationId, replyCode, replyText, exchange, routingKey);
}
);
template.setConfirmCallback((correlationData,ack,cause)->{
if (ack){
logger.info("消息成功消费,id:{},ack:{}",correlationData.getId(),ack);
}else{
logger.error("消息消费失败:correlationData: {},ack: {}",correlationData,cause);
}
});
return template;
}
@Bean
public SimpleRabbitListenerContainerFactory containerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
configurer.configure(factory, connectionFactory);
return factory;
}
@Bean(name = "orderEventNotifyExchange")
public DirectExchange orderEventNotifyExchange()
{
DirectExchange directExchange = new DirectExchange(ExchangeEnum.ORDER_EVENT_NOTIFY_DIRECT_EXCHANGE.getName());
return directExchange;
}
@Bean(name = "orderEventNotifyQueue")
public Queue orderEventNotifyQueue()
{
Queue queue = new Queue(QueueEnum.ORDER_EVENT_NOTIFY_DIRECT_QUEUE.getName());
return queue;
}
@Bean
public Binding orderEventNotifyBinding(@Qualifier(value = "orderEventNotifyExchange") DirectExchange orderEventNotifyExchange, @Qualifier(value = "orderEventNotifyQueue") Queue orderEventNotifyQueue)
{
Binding binding = BindingBuilder.bind(orderEventNotifyQueue).to(orderEventNotifyExchange).with(QueueEnum.ORDER_EVENT_NOTIFY_DIRECT_QUEUE.getRoutingKey());
logger.info("orderEventNotifyBinding实例化成功");
return binding;
}
@Bean(name = "orderCallExchange")
public TopicExchange orderCallExchange()
{
TopicExchange directExchange = new TopicExchange(ExchangeEnum.ORDER_CREATE_EXCHANGE.getName());
return directExchange;
}
@Bean(name = "orderCallQueue")
public Queue orderCallQueue()
{
Queue queue = new Queue(QueueEnum.ORDER_CREATE_QUEUE.getName());
return queue;
}
@Bean
public Binding orderCallBinding(@Qualifier(value = "orderCallExchange") TopicExchange orderCallExchange, @Qualifier(value = "orderCallQueue") Queue orderCallQueue)
{
Binding binding = BindingBuilder.bind(orderCallQueue).to(orderCallExchange).with(QueueEnum.ORDER_CREATE_QUEUE.getRoutingKey());
logger.info("orderCallBinding实例化成功");
return binding;
}
@Bean(name = "orderCreateDelayExchange")
public DirectExchange orderCreateDelayExchange()
{
return new DirectExchange(ExchangeEnum.ORDER_CREATE_DELAY_EXCHANGE.getName());
}
@Bean(name = "orderCreateDelayQueue")
public Queue orderCreateDelayQueue()
{
Map<String, Object> params = new HashMap<>();
// x-dead-letter-exchange 声明了队列里的死信转发到的DLX名称,
params.put("x-dead-letter-exchange", ExchangeEnum.ORDER_CREATE_EXCHANGE.getName());
// x-dead-letter-routing-key 声明了这些死信在转发时携带的 routing-key 名称。
params.put("x-dead-letter-routing-key", QueueEnum.ORDER_CREATE_QUEUE.getRoutingKey());
return new Queue(QueueEnum.ORDER_CREATE_DELAY_QUEUE.getName(), true, false, false, params);
}
@Bean
public Binding orderCreateDelayBinding(@Qualifier(value = "orderCreateDelayQueue") Queue orderCreateDelayQueue)
{
Binding binding = BindingBuilder.bind(orderCreateDelayQueue).to(orderCreateDelayExchange()).with(QueueEnum.ORDER_CREATE_DELAY_QUEUE.getRoutingKey());
logger.info("orderCreateDelayBinding实例化成功");
return binding;
}
/**
* 延迟队列配置
* <p>
* 1、params.put("x-message-ttl", 5 * 1000);
* 第一种方式是直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活,(当然二者是兼容的,默认是时间小的优先)
* 2、rabbitTemplate.convertAndSend(book, message -> {
* message.getMessageProperties().setExpiration(2 * 1000 + "");
* return message;
* });
* 第二种就是每次发送消息动态设置延迟时间,这样我们可以灵活控制
**/
@Bean
public Queue writeOffDelayQueue() {
Map<String, Object> params = new HashMap<>();
// x-dead-letter-exchange 声明了队列里的死信转发到的DLX名称,
params.put("x-dead-letter-exchange", ExchangeEnum.WRITE_OFF_EXCHANGE.getName());
// x-dead-letter-routing-key 声明了这些死信在转发时携带的 routing-key 名称。
params.put("x-dead-letter-routing-key", QueueEnum.WRITE_OFF_QUEUE.getRoutingKey());
return new Queue(QueueEnum.WRITE_OFF_DELAY_QUEUE.getName(), true, false, false, params);
}
/**
* 需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
* 这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”,则只有被标记为“dog”的消息才被转发,
* 不会转发dog.puppy,也不会转发dog.guard,只会转发dog。
* @return DirectExchange
*/
@Bean
public DirectExchange writeOffDelayExchange() {
return new DirectExchange(ExchangeEnum.WRITE_OFF_DELAY_EXCHANGE.getName());
}
@Bean
public Binding dlxWriteOffBinding() {
return BindingBuilder.bind(writeOffDelayQueue()).to(writeOffDelayExchange()).with(QueueEnum.WRITE_OFF_DELAY_QUEUE.getRoutingKey());
}
@Bean
public Queue writeOffQueue() {
return new Queue(QueueEnum.WRITE_OFF_QUEUE.getName(), true);
}
/**
* 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。
* 符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
**/
@Bean
public TopicExchange writeOffTopicExchange() {
return new TopicExchange(ExchangeEnum.WRITE_OFF_EXCHANGE.getName());
}
@Bean
public Binding writeOffBinding() {
// TODO 如果要让延迟队列之间有关联,这里的 routingKey 和 绑定的交换机很关键
return BindingBuilder.bind(writeOffQueue()).to(writeOffTopicExchange()).with(QueueEnum.WRITE_OFF_QUEUE.getRoutingKey());
}
}
生产者
package com.wt.console.base.config;
import com.wt.journey.enums.ExchangeEnum;
import com.wt.journey.enums.QueueEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;
/**
* @author liufan
* @version 1.0
* @date 2019/11/28 11:20
*/
@Component
@Slf4j
public class MQProducer {
private RabbitTemplate rabbitTemplate;
@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
public MQProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendOrderEventNotifyDirect(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(ExchangeEnum.ORDER_EVENT_NOTIFY_DIRECT_EXCHANGE.getName(), QueueEnum.ORDER_EVENT_NOTIFY_DIRECT_QUEUE.getRoutingKey(), content, correlationId);
log.info("发送时间 - {},发送内容 - {},correlationId - {}", LocalDateTime.now(),content,correlationId);
}
public void sendOrderCreateDelayDirect(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(ExchangeEnum.ORDER_CREATE_DELAY_EXCHANGE.getName(),QueueEnum.ORDER_CREATE_DELAY_QUEUE.getRoutingKey(),content,message -> {
//设置该消息延时120秒可消费
message.getMessageProperties().setExpiration(120 * 1000 + "");
return message;
});
log.info("发送时间 - {},发送内容 - {},correlationId - {}", LocalDateTime.now(),content,correlationId);
}
/**
* 核销补偿
* @author ayuanz
* @date 2019/12/3 11:52
* @param time 延迟时间
* @return void
**/
public void sendWriteOffDelayDirect(String content,Integer time) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
amqpTemplate.convertAndSend(ExchangeEnum.WRITE_OFF_DELAY_EXCHANGE.getName(),QueueEnum.WRITE_OFF_DELAY_QUEUE.getRoutingKey(),content,message -> {
//动态设置该消息延时可消费
message.getMessageProperties().setExpiration(time + "");
return message;
});
//log.info("发送时间 - {},发送内容 - {} ,延迟时间-{},correlationId - {}", LocalDateTime.now(),content,time,correlationId);
log.info("【核销补偿发送的消息】 - 【发送时间】 - [{}]- 【延迟时间】 - [{}]-【内容】 - [{}] -【correlationId】 - [{}]", new Date(), time, content,correlationId);
}
}
枚举
package com.wt.journey.enums;
import lombok.Getter;
@Getter
public enum QueueEnum {
/**
* 订单事件详情通知消息队列
*/
ORDER_EVENT_NOTIFY_DIRECT_QUEUE("journey.order.event.notify","journey.order.event.notify"),
/**
* 订单创建-延时队列
*/
ORDER_CREATE_DELAY_QUEUE("journey.order.create.delay","journey.order.create.delay"),
/**
* 订单创建-队列
*/
ORDER_CREATE_QUEUE("journey.call.order","journey.call.order"),
/**
* 核销补偿-死信队列
* @author ayuanz
* @date 2019/12/3 11:49
**/
WRITE_OFF_DELAY_QUEUE("journey.write.off.delay.queue","journey.write.off.delay"),
/**
* 核销补偿-延迟队列
* @author ayuanz
* @date 2019/12/3 11:49
**/
WRITE_OFF_QUEUE("journey.write.off.queue","journey.write.off"),
;
/**
* 队列名称
*/
private String name;
/**
* 队列路由键
*/
private String routingKey;
QueueEnum(String name, String routingKey) {
this.name = name;
this.routingKey = routingKey;
}
}
package com.wt.journey.enums;
import lombok.Getter;
@Getter
public enum ExchangeEnum {
/**
* 订单事件详情通知
*/
ORDER_EVENT_NOTIFY_DIRECT_EXCHANGE("journey.order.event.notify.direct.exchange"),
/**
* 订单创建-延时交换器
*/
ORDER_CREATE_DELAY_EXCHANGE("journey.order.create.delay.exchange"),
/**
* 订单创建-交换器
*/
ORDER_CREATE_EXCHANGE("journey.call.order.exchange"),
/**
* 核销补偿 死信
* @author ayuanz
* @date 2019/12/3 11:49
**/
WRITE_OFF_DELAY_EXCHANGE("journey.write.off.delay.exchange"),
/**
* 核销补偿 队列
* @author ayuanz
* @date 2019/12/3 11:49
**/
WRITE_OFF_EXCHANGE("journey.write.off.exchange"),
;
private String name;
ExchangeEnum(String name) {
this.name = name;
}
}
消费者
package com.wt.console.base.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.rabbitmq.client.Channel;
import com.wt.api.client.OrderRemote;
import com.wt.api.client.VegaServiceRemote;
import com.wt.api.dto.PublicOrderDTO;
import com.wt.base.user.model.dto.UserExtendInfoDTO;
import com.wt.console.base.config.MQProducer;
import com.wt.console.base.context.RtnInfo;
import com.wt.console.base.exception.SysException;
import com.wt.console.module.order.service.OrderService;
import com.wt.gus.api.client.UserExtendInfoRemote;
import com.wt.journey.dto.CancelOrderDTO;
import com.wt.journey.dto.EventNotifyDTO;
import com.wt.journey.dto.WriteOffMQDTO;
import com.wt.journey.enums.*;
import com.wt.journey.model.JourneyOrder;
import com.wt.journey.model.OrderTrack;
import com.wt.journey.model.WriteOffError;
import com.wt.journey.vo.OrderNoVO;
import com.wt.journey.vo.QueryOrderDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.SQLManager;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author liufan
* @version 1.0
* @date 2019/11/28 11:25
*/
@Component
@Slf4j
public class ConsumerService {
private static final String CHAR_SET = "utf-8";
@Autowired
private OrderService orderService;
@Autowired
private CaoCaoService caoCaoService;
@Autowired
private VegaServiceRemote vegaServiceRemote;
@Autowired
private MQProducer mqProducer;
@Autowired
private UserExtendInfoRemote userExtendInfoRemote;
@Autowired
private SQLManager sqlManager;
@Autowired
private OrderRemote orderRemote;
@RabbitListener(queues = "journey.order.event.notify",containerFactory = "containerFactory")
public void orderEventNotify(@Payload Message message, Channel channel) {
final long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
String content = new String(message.getBody(), CHAR_SET);
EventNotifyDTO eventNotifyDTO = JSON.parseObject(content, new TypeReference<EventNotifyDTO>() {
});
log.info("=========journey.order.event.notify===========start=== {} " , content);
String orderNo = eventNotifyDTO.getExt_order_id();
int type = OrderTypeEnum.REAL_TIME.getCode();
JourneyOrder journeyOrder = orderService.getOrderByOrderNo(orderNo,type);
if (journeyOrder == null || journeyOrder.getId() == null) {
channel.basicAck(deliveryTag,false);
return;
}
//查询曹操订单详情
String sourceOrderNo = eventNotifyDTO.getOrder_id();
RtnInfo<QueryOrderDetailVO> rtnInfo = caoCaoService.queryOrderDetail(sourceOrderNo);
if (!CaoCaoErrorEnum.SUCCESS.getCode().equals(rtnInfo.getCode())){
//查询失败
throw new SysException(rtnInfo.getMsg());
}
int eventType = Integer.parseInt(eventNotifyDTO.getEvent());
int orderStatus = rtnInfo.getData().getBasicOrderVO().getStatus();
if (orderStatus!=journeyOrder.getStatus()){
OrderTrack orderTrack = OrderTrack.builder()
.orderId(journeyOrder.getId())
.eventDesc(EventStatusEnum.getMsgByCode(eventType))
.eventType(eventType).build();
orderService.syncOrderInfo(rtnInfo.getData(),journeyOrder,orderTrack);
}
channel.basicAck(deliveryTag,false);
}catch (Exception e){
log.error("=====消息处理异常: {}",e);
try {
channel.basicRecover();
}catch (IOException e1){
e1.printStackTrace();
}
}
}
/**
* 120发起取消订单请求
* @param message
* @param channel
*/
@RabbitListener(queues = "journey.call.order",containerFactory = "containerFactory")
public void orderCreateDelay(@Payload Message message, Channel channel) {
final long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
String content = new String(message.getBody(), CHAR_SET);
OrderNoVO orderNoVO = JSON.parseObject(content, new TypeReference<OrderNoVO>() {
});
log.info("=========journey.call.order===========start=== {} " , content);
String orderNo = orderNoVO.getOrderNo();
int type = OrderTypeEnum.REAL_TIME.getCode();
JourneyOrder journeyOrder = orderService.selectStatusByOrderNo(orderNo,type);
if (journeyOrder == null || journeyOrder.getId() == null) {
channel.basicAck(deliveryTag,false);
return;
}
//作为第三方系统发起取消订单请求
int status = journeyOrder.getStatus();
if (OrderStatusEnum.NO_ORDER.getCode()==status){
Long caoCaoOrderId = journeyOrder.getSourceOrderCode();
CancelOrderDTO cancelOrderDTO = CancelOrderDTO.builder()
.cancelCode(OrderCancelEnum.OrderCancelWhoEnum.ORDER_TIME_OUT.getCode())
.cancelReason(OrderCancelEnum.OrderCancelWhoEnum.ORDER_TIME_OUT.getMsg())
.orderId(caoCaoOrderId)
.whoCancel(WhoCancelEnum.WT_SYSTEM.getCode())
.build();
RtnInfo rtnInfo = caoCaoService.cancelOrder(cancelOrderDTO);
log.info(rtnInfo.toString());
}
channel.basicAck(deliveryTag,false);
}catch (Exception e){
log.error("=====消息处理异常: {}",e);
try {
channel.basicRecover();
}catch (IOException e1){
e1.printStackTrace();
}
}
}
/**
* 核销补偿消费机制
* @author ayuanz
* @date 2019/12/3 15:06
* @param message, channel
* @return void
**/
@RabbitListener(queues = "journey.write.off.queue",containerFactory = "containerFactory")
public void writeOff(@Payload Message message, Channel channel) {
final long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
String content = new String(message.getBody(), CHAR_SET);
WriteOffMQDTO writeOffMQDTO = JSON.parseObject(content, new TypeReference<WriteOffMQDTO>() {
});
//log.info("=========journey.write.off.delay===========start=== {} " , content);
log.info("【核销补偿监听的消息】 - 【消费时间】 - [{}]- 【内容】 - [{}]", new Date(), content);
//优惠券补偿机制
if (CouponTypeEnum.COUPON.getCode() == writeOffMQDTO.getType()) {
//调优惠券核销
try {
if (0 != vegaServiceRemote.checkedCouponByUseId(Long.parseLong(writeOffMQDTO.getData())).getCode()) {
//核销失败,放入mq做补偿机制,超过5次即放弃核销
if (5 < writeOffMQDTO.getNumber()) {
sqlManager.insertTemplate(WriteOffError.builder().type(CouponTypeEnum.COUPON.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).build());
channel.basicAck(deliveryTag, false);
return;
}
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(CouponTypeEnum.COUPON.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}catch (Exception e){
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(CouponTypeEnum.COUPON.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}
//红包补偿机制
if (CouponTypeEnum.RED_PACKET.getCode() == writeOffMQDTO.getType()) {
try {
//扣红包
UserExtendInfoDTO userExtendInfoDTO = null;
userExtendInfoDTO = UserExtendInfoDTO.builder().userId(writeOffMQDTO.getUserId())
.amt(BigDecimal.valueOf(Double.parseDouble(writeOffMQDTO.getData()))).build();
if (0 != userExtendInfoRemote.updateUserExtendInfo(userExtendInfoDTO).getCode()) {
//核销失败,放入mq做补偿机制
if (5 < writeOffMQDTO.getNumber()) {
sqlManager.insertTemplate(WriteOffError.builder().type(CouponTypeEnum.RED_PACKET.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).build());
channel.basicAck(deliveryTag, false);
return;
}
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(CouponTypeEnum.RED_PACKET.getCode()).userId(writeOffMQDTO.getUserId()).data(writeOffMQDTO.getData()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}catch (Exception e){
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(CouponTypeEnum.RED_PACKET.getCode()).userId(writeOffMQDTO.getUserId()).data(writeOffMQDTO.getData()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}
//曹操确认补偿机制
if (WriteOffErrorEnum.caocao.getCode() == writeOffMQDTO.getType()) {
String[] split = writeOffMQDTO.getData().split("\\|");
com.wt.console.base.context.RtnInfo rtnInfo = caoCaoService.feeConfirm(split[0] + "", BigDecimal.valueOf(Long.parseLong(split[1])));
if (!CaoCaoErrorEnum.SUCCESS.getCode().equals(rtnInfo.getCode())) {
//核销失败,放入mq做补偿机制
if (5 < writeOffMQDTO.getNumber()) {
sqlManager.insertTemplate(WriteOffError.builder().type(WriteOffErrorEnum.caocao.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).build());
channel.basicAck(deliveryTag, false);
return;
}
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(WriteOffErrorEnum.caocao.getCode()).userId(writeOffMQDTO.getUserId()).data(writeOffMQDTO.getData()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}
//公共订单补偿机制
if (WriteOffErrorEnum.publicOrder.getCode() == writeOffMQDTO.getType()) {
try {
PublicOrderDTO publicOrderDTO = JSON.parseObject(writeOffMQDTO.getData(), PublicOrderDTO.class);
if (0 != orderRemote.updateOrder(publicOrderDTO).getCode()) {
//核销失败,放入mq做补偿机制
if (5 < writeOffMQDTO.getNumber()) {
sqlManager.insertTemplate(WriteOffError.builder().type(WriteOffErrorEnum.publicOrder.getCode()).data(writeOffMQDTO.getData()).userId(writeOffMQDTO.getUserId()).build());
channel.basicAck(deliveryTag, false);
return;
}
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(WriteOffErrorEnum.publicOrder.getCode()).userId(writeOffMQDTO.getUserId()).data(writeOffMQDTO.getData()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}catch (Exception e){
mqProducer.sendWriteOffDelayDirect(JSON.toJSONString(WriteOffMQDTO.builder().type(WriteOffErrorEnum.publicOrder.getCode()).userId(writeOffMQDTO.getUserId()).data(writeOffMQDTO.getData()).number(writeOffMQDTO.getNumber() + 1).build()), writeOffMQDTO.getNumber() * 5 * 1000);
}
}
channel.basicAck(deliveryTag, false);
} catch(Exception e){
log.error("=====消息处理异常: {}", e);
}
}
}