rabbit使用

登录http://localhost:15672/#/queues   guest/guest

添加交换机

 添加队列,并绑定交换机

 

rabbitmq:
    addresses: 192.168.1.1:5672
    username: guest
    password: jingzhiadmin
    virtual-host: /
    publisher-confirms: true #confirm模式
    publisher-returns: true #return机制
    template:
      mandatory: true #与return机制结合配置次属性
    connection-timeout: 5000
    listener: 
       simple: 
          prefetch: 5 #定义消费者同时处理5个消息
          acknowledge: manual #消息手动确认   
package com.jzlife.management.rabbitmq;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.SerializerMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
public class RabbitMqConfig {

	@Bean
	public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
		factory.setConnectionFactory(connectionFactory);
//		factory.setMessageConverter(new Jackson2JsonMessageConverter());
		factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
		return factory;
	}

//	@Bean
//	@Scope("prototype")
//	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
//		RabbitTemplate template = new RabbitTemplate(connectionFactory);
//		template.setMandatory(true);
//		template.setMessageConverter(new SerializerMessageConverter());
//		return template;
//
//	}
	/**
	 * 如果消息没有到exchange,则confirm回调,ack=false
	 * 
	 * 如果消息到达exchange,则confirm回调,ack=true
	 * 
	 * exchange到queue成功,则不回调return
	 * 
	 * exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)
	 */
}

发送到mq

package com.jzlife.management.rabbitmq;

import com.jzlife.management.constant.MqConstant;
import com.jzlife.management.entity.mq.MqRecord;
import com.jzlife.management.entity.mq.OrderApplyMessage;
import com.jzlife.management.service.MqRecordService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

@Component
public class TestOrderApplySender {
	private Logger logger = LogManager.getLogger(getClass());
	@Autowired
	RabbitTemplate rabbitTemplate;
 

	/**
	 * 生产message
	 * 
	 * @param messge
	 */
	public void sendMessage(Integer i) {
//		// 设置发送后的返回调用
//		rabbitTemplate.setConfirmCallback(confirmCallback);
//
//		// 发送前的业务处理
//		CorrelationData correlationData = new CorrelationData();
//		correlationData.setId(orderApplyMessage.getMessageId());
//		rabbitTemplate.convertAndSend(MqConstant.QUEUES_ORDER_APPLY, orderApplyMessage, correlationData);
		Map<String,Object> objMapData=new HashMap<String, Object>();
		objMapData.put("aa", i);
		System.out.println("fasongle------------1");
		rabbitTemplate.convertAndSend("exchange-test", null, objMapData);
		System.out.println("fasongle------------");
	}

//	final ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
//		@Override
//		public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//			logger.info("confirmCallback correlationData:" + correlationData);
//			String correlationId = correlationData.getId();// 消息id
//
//			 System.out.println("ack"+ack);
//		}
//
//	};

}

接受fanout模式

package com.jzlife.management.rabbitmq;

import com.jzlife.management.aop.PlatAuth;
import com.jzlife.management.constant.MqConstant;
import com.rabbitmq.client.Channel;

import java.util.Map;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

/**
 * @author fuxubing
 */
@Component
public class TestOrderApplyListener {

	/**
	 * 消费message exchange = @Exchange(value = "order-exchange", durable = "true",
	 * type = "topic", ignoreDeclarationExceptions = "true")
	 *
	 * @param message
	 * @param channel
	 * @throws Exception
	 */
//	@RabbitListener(queues = MqConstant.QUEUES_ORDER_APPLY)
	@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "queue-exchange-test"), exchange = @Exchange(value = "exchange-test", type = "fanout")

	))
	@RabbitHandler
	public void onMessage2(@SuppressWarnings("rawtypes") Message message, @Payload Map data, Channel channel,
			@Headers Map<String, String> headers) throws Exception {
		Thread.sleep(10);
		System.out.println(data);
		Long deliveryTag = (Long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
		channel.basicAck(deliveryTag, false);
	}

}

另外情况 使用默认的交换机,也就是队列没有强制绑定交换机,发起时用的队列名

package com.jzlife.management.rabbitmq;

import com.jzlife.management.constant.MqConstant;
import com.jzlife.management.entity.mq.MqRecord;
import com.jzlife.management.entity.mq.OrderApplyMessage;
import com.jzlife.management.service.MqRecordService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;

@Component
public class OrderApplySender {
	private Logger logger = LogManager.getLogger(getClass());
	@Autowired
	RabbitTemplate rabbitTemplate;

	@Autowired
	MqRecordService mqRecordService;

	/**
	 * 生产message
	 * 
	 * @param messge
	 */
	public void sendMessage(OrderApplyMessage orderApplyMessage) {
		// 设置发送后的返回调用
		rabbitTemplate.setConfirmCallback(confirmCallback);

		// 发送前的业务处理
		CorrelationData correlationData = new CorrelationData();
		correlationData.setId(orderApplyMessage.getMessageId());
		rabbitTemplate.convertAndSend(MqConstant.QUEUES_ORDER_APPLY, orderApplyMessage, correlationData);
	}

	final ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
		@Override
		public void confirm(CorrelationData correlationData, boolean ack, String cause) {
			logger.info("confirmCallback correlationData:" + correlationData);
			String correlationId = correlationData.getId();// 消息id

			MqRecord record =mqRecordService.selectByCorrelationId(correlationId);
			if (ack) {
				// 发送成功 ,把消息订单状态改为2,说明消息发送成功了
				record.setStatus(MqConstant.QUEUES_STATUS_LINEUP);
			} else {
				//失败情况
				if(record.getFailurePostNumber().equals(2)) {//失败次数2(加首次)也就发了3次就结束
					record.setStatus(MqConstant.QUEUES_STATUS_FAIL);//失败
					record.setFailReason("发送至消息队列失败");
				}else {
					Calendar nowTime = Calendar.getInstance();
					nowTime.add(Calendar.SECOND, 30); //30秒
					record.setFailurePostTime(nowTime.getTime());//下次发送时间
				}
				
			}
			mqRecordService.updateBycorrelationId(record);
		}

	};

}
package com.jzlife.management.rabbitmq;

import com.jzlife.management.constant.MqConstant;
import com.jzlife.management.constant.NoticeActionEnum;
import com.jzlife.management.entity.InvenCalcul.DateTimeServiceItemInfo;
import com.jzlife.management.entity.InvenCalcul.TimeServiceItemInfo;
import com.jzlife.management.entity.mq.MqRecord;
import com.jzlife.management.entity.mq.OrderApplyMessage;
import com.jzlife.management.entity.mq.OrderServiceTime;
import com.jzlife.management.notice.NoticeExecutor;
import com.jzlife.management.service.InventoryCalculationService;
import com.jzlife.management.service.MqRecordService;
import com.jzlife.management.service.OrderApplyService;
import com.jzlife.management.service.UnitCommodityService;
import com.jzlife.management.util.JsonUtil;
import com.jzlife.management.util.ResponseUtil;
import com.jzlife.management.utils.OrderUtil;
import com.jzlife.management.vo.SelectStockAndWorkerId;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 11
 */
@Component
public class OrderApplyListener {

    //	@Resource
//	private OrderService orderService;
    @Autowired
    OrderApplyService orderApplyService;

    @Resource
    private InventoryCalculationService inventoryCalculationService;
    @Resource
    private UnitCommodityService unitCommodityService;
    @Autowired
    MqRecordService mqRecordService;
    @Autowired
    private NoticeExecutor noticeExecutor;
    private static final Logger logger = LoggerFactory.getLogger(OrderApplyListener.class);

    /**
     * 消费message exchange = @Exchange(value = "order-exchange", durable = "true",
     * type = "topic", ignoreDeclarationExceptions = "true")
     *
     * @param message
     * @param channel
     * @throws Exception
     */
    @RabbitListener(queues = MqConstant.QUEUES_ORDER_APPLY)
    @RabbitHandler
    public void onMessage2(@SuppressWarnings("rawtypes") Message message, Channel channel) throws Exception {

        logger.info("消费端22222Payload: " + JsonUtil.getJson(message.getPayload()));
        Long deliveryTag = (Long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);// 手签\
        /**
         * 若ack失败 程序断开于rabbitmq的链接后 unacked的消息状态会重新变为ready 等待消费。
         * 代码更新后,server应用连接rabbitmq 就会重新消费掉消息。
         */

        // 业务处理
        OrderApplyMessage orderApplyMessage = JsonUtil.getEntity(message.getPayload(), OrderApplyMessage.class);
        if (null == orderApplyMessage) {
            messageStatus(message, channel, null, MqConstant.ORDER_STATUS_FAIL, "下单数据异常空值");
        }

        assert orderApplyMessage != null;

        // 判断库存
        Map<String, Object> map = unitCommodityService.selectByCommodityNo(orderApplyMessage.getUnitCommodityNo());
        if (map == null) {
            messageStatus(message, channel, null, MqConstant.ORDER_STATUS_FAIL, "商品不存在");
            return;
        }

        Long unitCommdId = (Long) map.get("id");
        List<OrderServiceTime> orderServiceTimeList = orderApplyMessage.getOrderServiceTimeList();
        SelectStockAndWorkerId selectStockAndWorkerId = OrderUtil.setStockParams(unitCommdId, orderServiceTimeList);
        List<DateTimeServiceItemInfo> itemInfos = inventoryCalculationService
                .selectWorkerToService(selectStockAndWorkerId);

        if (itemInfos.isEmpty()) {
            messageStatus(message, channel, null, MqConstant.ORDER_STATUS_FAIL, "库存数不足");
            return;
        }

        for (DateTimeServiceItemInfo itemInfo : itemInfos) {
            for (TimeServiceItemInfo timeServiceItemInfo : itemInfo.getTimeList()) {
                Integer stockNumber = timeServiceItemInfo.getStockNumber();
                if (stockNumber <= 0) {
                    messageStatus(message, channel, null, MqConstant.ORDER_STATUS_FAIL, "库存数不足");
                    return;
                }
            }
        }

        // 下订单
        String orderNo = null;
        Object object;
        Map<String, Object> map1 = new HashMap<>(16);
        map1.put("action", NoticeActionEnum.ORDER_SUCCESS);
        try {
            orderNo = orderApplyService.createOrder(orderApplyMessage, itemInfos);
            messageStatus(message, channel, orderNo, MqConstant.ORDER_STATUS_OK, null);
            map1.put("orderNo", orderNo);
            object = ResponseUtil.ok(map1);

        } catch (Exception e) {
            e.printStackTrace();
            messageStatus(message, channel, null, MqConstant.ORDER_STATUS_FAIL, "下单异常|" + getErrorMsg(e));
            object = ResponseUtil.fail(map1);
        }

        noticeExecutor.sendNotice(object, orderApplyMessage.getNoticeUrl());
    }

    /**
     * 处理消息状态
     *
     * @param message
     * @param channel
     * @param orderNo
     * @param orderStatus
     * @param failReason
     * @throws IOException
     */
    private void messageStatus(@SuppressWarnings("rawtypes") Message message, Channel channel, String orderNo,
                               Integer orderStatus, String failReason) throws IOException {

        OrderApplyMessage orderApplyMessage = JsonUtil.getEntity(message.getPayload(), OrderApplyMessage.class);

        MqRecord mqRecord = new MqRecord();
        mqRecord.setCorrelationId(orderApplyMessage == null ? null : orderApplyMessage.getMessageId());
        mqRecord.setOrderNo(orderNo);
        mqRecord.setOrderStatus(orderStatus);
        mqRecord.setFailReason(failReason);
        mqRecordService.updateBycorrelationId(mqRecord);
    }
    
    
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值