天天看點

springboot內建rabbitmq,異步發送郵件功能實作

作者:mortyc137

1.配置qq郵箱的賬号、密碼;配置rabbitmq的ip、使用者名、密碼

springboot內建rabbitmq,異步發送郵件功能實作

qq郵箱配置

springboot內建rabbitmq,異步發送郵件功能實作

rabbitmq配置

2.聲明隊列、交換機、讓隊列綁定交換機,并且攜帶路由key(用的是路由模式)

設定消息和交換機持久性,是為了防止消息丢失

springboot內建rabbitmq,異步發送郵件功能實作

隊列交換機綁定

3.為了保證生産者不丢失消息,需要讓生産者确認消息

消息有一個唯一的消息id,mq收到消息後,會傳回一個結果給發送者,表示消息處理成功

傳回的結果有兩種方式

a.發送者确認:消息沒有投遞到交換機,則傳回ack,反之則傳回nack

b.發送者回執:消息到交換機了,但是沒有路由到隊列,則傳回ack,以及路由失敗的原因。

springboot內建rabbitmq,異步發送郵件功能實作

發送者确認和發送者回執

消息投遞成功後,調用updateMailSendLogStatus方法,修改消息資料庫消息表中等于msgId的記錄的狀态字段(status等于1代表消息發送成功)

springboot內建rabbitmq,異步發送郵件功能實作

調用發送者确認和發送者回執方法

springboot內建rabbitmq,異步發送郵件功能實作

消息表

4.錄入使用者資訊後,生成唯一的msgId,并且将消息發送給消費者

springboot內建rabbitmq,異步發送郵件功能實作

消息發送代碼

5.消費者接收消息,開啟手動确認模式,傳回消息給生産者

使用redis,查詢redis緩存是否存在msgId,如果存在直接将該消息标記為已消費(先判斷redis是否存在msgId是為了避免消息重複消費,保證了接口的幂等性。channel.basicAck(tag, false):标記該消息已經成功消費了),否則,發送郵件(發送郵件即消費消息)

springboot內建rabbitmq,異步發送郵件功能實作

使用redis,避免消息重複消費

6.redis不存在msgId,則消費該消息

如果redis不存在msgId,說明消息沒有被消費過,則可以消費消息。發送完郵件後,将msgId存入到redis中,下次同樣的消息來後,就不會被消費。

springboot內建rabbitmq,異步發送郵件功能實作

消費消息

7.消費失敗重試機制

使用Quartz定時任務架構,定時掃描資料庫消息表中,狀态等于0的記錄(狀态等于0代表消息投遞中,消息者還沒有消費到消息),對這些記錄進行周遊,并判斷記錄中重試次數:count是否大于3,小于等于3,則再次對消息發送;反之,重試次數大于3,則将資料庫這條記錄的狀态直接設定為:消息投遞失敗。

springboot內建rabbitmq,異步發送郵件功能實作

消費失敗重試

總結:

消息可靠性保證:

1.發送者确認和發送者回執

2.消息和隊列持久化

3.消費者失敗重置

繼續閱讀