對於消息隊列的理解。

咱們在開發的過程當中,會遇到像這樣的狀況:php

  好比,咱們須要開發一個給註冊用戶發送郵件的功能。其實製做起來並非很難,無非就是兩步,mysql

    一、獲取須要發送郵件的郵箱,並填寫發送內容。程序員

    二、發送。redis

這功能實現起來很簡單,也很寫,對吧!sql

那麼,如今問題來了。併發

我如今有好百萬的併發,幾百萬個用戶同時都在註冊(固然這裏是假設)。這麼高併發的狀況下,咱們仍是用同步的方式去執行上面的1和2這兩個步驟。高併發

我能夠很負責的告訴你們,必定會出現發送失敗的案例,並且會不少。post

那怎麼解決這樣的問題呢?spa

消息隊列!!!線程

這裏咱們就引入了消息隊列的概念。在理解這個概念以前,咱們先來看一個生活中的小例子:

  咱們都到餐廳去吃過飯對吧,服務員點單和廚師作菜,必定是服務員點單遠遠快於廚師作菜。那麼問題再一次來了,若是服務員點單和廚師作菜是單線程的同步執行的。

  那麼咱們做爲顧客,必定會有很大的怨言。由於咱們要等到上一座點單的是的菜上齊事後才能點餐。

  可是在現實生活中,沒有一家餐廳是這樣的。一般餐廳中服務員點單和廚師作菜沒有直接聯繫,服務員只管點單,點單成功後記錄在一個介質上(這裏假設爲記錄在紙上),而後傳遞給後廚,後廚再按照單子的先後順序依次製做。

  其實,咱們上面天天都經歷的這個情形就是一個典型的消息隊列:消息發佈者(服務員),將消息存入消息隊列(紙質點單記錄),消息執行者(廚師)從消息隊列取得消息並執行。

看了上面的例子,我相信絕大部分人對消息隊列都應該有了必定的認識了。

下面爲消息隊列的一個抽象圖。(生產者:服務員、消費者:廚師)

  

下面,咱們來說一下如何使用消息隊列實現百萬併發的郵件發送(保證每一封郵件都能發送成功,除非客戶填寫了一個錯誤的郵件地址,這裏咱們不考慮這種狀況)

須要注意的是,存儲消息的介質有不少,咱們能夠根據需求隨意選擇,不用拘泥於redis的list。這裏咱們暫且選擇mysql做爲消息的存儲介質。

咱們新建一個表,用於存儲消息。代表爲MQ,含有三個字段id、u_email(用戶郵箱)、post_content(發送內容)。

一、當用戶申請註冊的時候,將用戶的郵箱和發送內容(發送內容能夠視狀況而定,這裏的邏輯就具體問題具體分析了哈)存入MQ表,存入成功後立刻就能夠給用戶反饋。好比(請到您的郵箱查看郵件是否已發送到您的郵箱......)

二、用php實現一個定時器,定時從MQ表中取出數據,進行郵件發送。若是成功則從數據表MQ中刪除該條記錄(固然,通常咱們用邏輯刪除),若是沒有成功,則不刪除。

優勢:

一、後臺運行,前臺無需等待,立刻能夠給客戶以反應,友好度較高。

二、成功率高,失敗的記錄會自動重發,直到成功。

在工做中會遇到不少剛接觸消息隊列的程序員,誤覺得redis的list就是消息隊列。其實list只是redis的一種數據類型,它可以實現消息隊列功能而已。

作一個消息隊列的總結

  消息(Message)是指在應用之間傳送的數據,消息能夠很是簡單,好比只包含文本字符串,也能夠更復雜,可能包含嵌入對象。
  消息隊列(Message Queue)是一種應用間的通訊方式,消息發送後能夠當即返回,有消息系統來確保信息的可靠專遞,消息發佈者只管把消息發佈到MQ中而無論誰來取,

  消息使用者只管從MQ中取消息而無論誰發佈的,這樣發佈者和使用者都不用知道對方的存在。

推薦一個消息隊列的中間件,你們有時間能夠去了解:RabbitMQ

但願可以幫到有須要的人。

相關文章
相關標籤/搜索