我們在開發的過程中,會遇到像這樣的情況:
比如,我們需要開發乙個給註冊使用者傳送郵件的功能。其實製作起來並不是很難,無非就是兩步,
1、獲取需要傳送郵件的郵箱,並填寫傳送內容。
2、傳送。
這功能實現起來很簡單,也很寫,對吧!
那麼,現在問題來了。
我現在有好百萬的併發,幾百萬個使用者同時都在註冊(當然這裡是假設)。這麼高併發的情況下,我們還是用同步的方式去執行上面的1和2這兩個步驟。
我可以很負責的告訴大家,一定會出現傳送失敗的案例,而且會很多。
那怎麼解決這樣的問題呢?
訊息佇列!!!
這裡我們就引入了訊息佇列的概念。在理解這個概念之前,我們先來看乙個生活中的小例子:
我們都到餐廳去吃過飯對吧,服務員點單和廚師做菜,一定是服務員點單遠遠快於廚師做菜。那麼問題再一次來了,如果服務員點單和廚師做菜是單執行緒的同步執行的。
那麼我們作為顧客,一定會有很大的怨言。因為我們要等到上一座點單的是的菜上齊過後才能點餐。
但是在現實生活中,沒有一家餐廳是這樣的。通常餐廳中服務員點單和廚師做菜沒有直接聯絡,服務員只管點單,點單成功後記錄在乙個介質上(這裡假設為記錄在紙上),然後傳遞給後廚,後廚再按照單子的前後順序依次製作。
其實,我們上面每天都經歷的這個情形就是乙個典型的訊息佇列:訊息發布者(服務員),將訊息存入訊息佇列(紙質點單記錄),訊息執行者(廚師)從訊息佇列取得訊息並執行。
看了上面的例子,我相信絕大部分人對訊息佇列都應該有了一定的認識了。
下面為訊息佇列的乙個抽象圖。(生產者:服務員、消費者:廚師)
下面,我們來講一下如何使用訊息佇列實現百萬併發的郵件傳送(保證每一封郵件都能傳送成功,除非客戶填寫了乙個錯誤的郵件位址,這裡我們不考慮這種情況)
需要注意的是,儲存訊息的介質有很多,我們可以根據需求隨意選擇,不用拘泥於redis的list。這裡我們暫且選擇mysql作為訊息的儲存介質。
我們新建乙個表,用於儲存訊息。表明為mq,含有三個欄位id、u_email(使用者郵箱)、post_content(傳送內容)。
1、當使用者申請註冊的時候,將使用者的郵箱和傳送內容(傳送內容可以視情況而定,這裡的邏輯就具體問題具體分析了哈)存入mq表,存入成功後馬上就可以給使用者反饋。比如(請到您的郵箱檢視郵件是否已傳送到您的郵箱......)
2、用php實現乙個定時器,定時從mq表中取出資料,進行郵件傳送。如果成功則從資料表mq中刪除該條記錄(當然,一般我們用邏輯刪除),如果沒有成功,則不刪除。
優點:
1、後台執行,前台無需等待,馬上可以給客戶以反應,友好度較高。
2、成功率高,失敗的記錄會自動重發,直到成功。
在工作中會遇到很多剛接觸訊息佇列的程式設計師,誤以為redis的list就是訊息佇列。其實list只是redis的一種資料型別,它能夠實現訊息佇列功能而已。
做乙個訊息佇列的總結:
訊息(message)是指在應用之間傳送的資料,訊息可以非常簡單,比如只包含文字字串,也可以更複雜,可能包含嵌入物件。
訊息佇列(message queue)是一種應用間的通訊方式,訊息傳送後可以立即返回,有訊息系統來確保資訊的可靠專遞,訊息發布者只管把訊息發布到mq中而不管誰來取,
訊息使用者只管從mq中取訊息而不管誰發布的,這樣發布者和使用者都不用知道對方的存在。
希望能夠幫到有需要的人。
對於訊息佇列的理解
訊息佇列可以簡單理解為 把要傳輸的資料放在佇列中。訊息佇列中介軟體是分布式系統中重要的元件,主要解決應用耦合,非同步訊息,流量削鋒等問題。1.解耦 比如說某乙個系統a要與其他系統打交道 即呼叫其中的方法 如果其它系統改變或者新增系統,那麼a系統都會改變,這樣的話耦合度比較高,比較麻煩。我們a系統將產...
訊息佇列的理解
訊息佇列的主要特點是非同步處理,主要目的是減少請求響應時間和解耦。所以主要的使用場景就是將比較耗時而且不需要即時 同步 返回結果的操作作為訊息放入訊息佇列。同時由於使用了訊息佇列,只要保證訊息格式不變,訊息的傳送方和接收方並不需要彼此聯絡,也不需要受對方的影響,即解耦和。例子 假設使用者在你的軟體中...
自己對於訊息機制的理解
一直對訊息機制的理解不夠深入,還有對遞迴的的理解不夠好 一直不明白為什麼這裡是這樣,那裡是那樣,自己撲該過才會恍然大悟 哦 原來是醬紫。開始第一次用訊息機制的時候覺得它還是用起來很不順手。不理解為什麼要加上訊息傳送的優先順序。還覺得這東西對方法執行的時序控制很不好,以至於寫了一大堆我自己都頂不順了的...