RabbitMQ教程

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);
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值