临海城市建设网站,举例说明网络营销的概念,行业网站名录,局域网小网站网站建设软件前言 上来先放一张设计图#xff0c;看这篇文章的前提是一定得写过或者了解这段业务#xff0c;不然会看不懂#xff0c;我下面将会给出我的理解#xff0c;尽量让大家明白
设计思想
TransactionalOverridepublic SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {…前言 上来先放一张设计图看这篇文章的前提是一定得写过或者了解这段业务不然会看不懂我下面将会给出我的理解尽量让大家明白
设计思想
TransactionalOverridepublic SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {//前面的代码略过只关注消息队列的入口 注意,这是整个mq系统的入口,调用了wmsFeignService.orderLockStock(lockVo)的时候就向stock.delay.queue这个延时队列(50min)里面添加了锁库存的消息50min之后如果过期此消息将会被自动路由(设计的时候就是这样设计的是mq自动做的路由不用写java代码)到死信队列stock.release.stock.queue中发送的类型是StockLockedTo对象意味着这条消息将会被OrderCloseListener的第一个监听函数监听到将会去解锁库存下面那个rabbitTemplate.convertAndSend(order-event-exchange,order.create.order,order.getOrder())是创建订单,订单将会在延时队列放30min直到付款或者取消如果取消或者30min后这个消息将被自动路由(设计的时候就是这样设计的是mq自动做的路由不用写java代码)到死信队列order.release.order.queue中这个时候OrderCloseListener是监听着order.release.order.queue的于是它将调用本类中的closeOrder()方法并将订单关闭这个消息路由到死信队列stock.release.stock.queue中,传输的是一个OrderTo对象条消息将会被OrderCloseListener的第二个监听器接收到所以正确是玩法是首先用户下好订单如果在30min内没有支付或者取消了订单那么证明这个订单是废单因此需要把锁了的库存给解锁了30min一到OrderCloseListener的第二个监听器将会去解锁订单50min后还会有一道保险也就是第一个监听器监听到50min过期的消息尝试去解锁订单形成双保险自动解锁。R r wmsFeignService.orderLockStock(lockVo);if (r.getCode() 0) {//锁定成功response.setOrder(order.getOrder());//TODO 订单创建成功发送消息给MQ/*** 这是往时限为1分钟的延迟队列传输的信息里面放着OrderEntity对象一分钟后被送往死信队列order.release.order.queue**/rabbitTemplate.convertAndSend(order-event-exchange,order.create.order,order.getOrder());//删除购物车里的数据redisTemplate.delete(CART_PREFIXmemberResponseVo.getId());return response;} else {//锁定失败String msg (String) r.get(msg);throw new NoStockException(msg);}//后面的代码略过}大家对着我上面给出的一大段中文注释自己去看看是不是这样的
我发现的细节
还有一个细节如果有两个监听器一起监听一个队列例如本项目
Slf4j
RabbitListener(queues stock.release.stock.queue)
Service
public class StockReleaseListener {Autowiredprivate WareSkuService wareSkuService;RabbitHandlerpublic void handleStockLockedRelease(StockLockedTo to, Message message, Channel channel) throws IOException {log.info(******50min了我怕你20min前出问题没解锁到这是第二道保险******);//具体代码}RabbitHandlerpublic void handleOrderCloseRelease(OrderTo orderTo, Message message, Channel channel) throws IOException {log.info(******30min了你订单还没支付或者已经取消我去解锁库存了******);//具体代码}}上面这两个代码我再次标明了这两个监听器的先后顺序以及作用如果还懵的现在应该大概明白了吧
我一开始是不知道到底是哪个会先接受消息后面发现这两个监听器不是去抢同一个消息的而是 去拿自己对应的消息的此话怎讲
例如第一个监听器它的第一个参数是StockLockedTo to意味着如果当时给这个消息队列存的对象是StockLockedTo的话将被这个监听器收到
第二个监听器它的第一个参数是OrderTo orderTo意味着如果当时给这个消息队列存的对象是OrderTo 的话将被这个监听器收到。
无论有几个监听器他们只会取到他们应该取到的消息所以放消息的时候要放好取出来的时候也得取好别放进去一个类取出来用另一个类取肯定是取不到的会报错。