谷粒商城RabbitMQ设计思想详解:消息队列双重保险设计
生活随笔
收集整理的這篇文章主要介紹了
谷粒商城RabbitMQ设计思想详解:消息队列双重保险设计
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
上來先放一張設計圖,看這篇文章的前提是一定得寫過或者了解這段業務,不然會看不懂,我下面將會給出我的理解,盡量讓大家明白
設計思想
@Transactional@Overridepublic 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_PREFIX+memberResponseVo.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 的話,將被這個監聽器收到。
無論有幾個監聽器,他們只會取到他們應該取到的消息,所以放消息的時候要放好,取出來的時候也得取好,別放進去一個類,取出來用另一個類取,肯定是取不到的,會報錯。
總結
以上是生活随笔為你收集整理的谷粒商城RabbitMQ设计思想详解:消息队列双重保险设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vr手机怎么看(手机如何看VR)
- 下一篇: 谷粒商城RabbitMQ锁库存逻辑详解-