消息隊列是分佈式系統中重要的組件,在不少生產環境如商品搶購等須要控制併發量的場景下都須要用到。
本部分主要介紹消息隊列的使用場景和消息隊列的兩種模式sql
消息隊列(Message Queue),是分佈式系統中重要的組件,其通用的使用場景能夠簡單地描述爲:
當不須要當即得到結果,可是併發量又須要進行控制的時候,差很少就是須要使用消息隊列的時候。
消息隊列主要解決了應用耦合、異步處理、流量削鋒等問題。
當前使用較多的消息隊列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,而部分數據庫如Redis、Mysql以及phxsql也可實現消息隊列的功能。數據庫
消息隊列在實際應用中包括以下四個場景:
l 應用耦合:多應用間經過消息隊列對同一消息進行處理,避免調用接口失敗致使整個過程失敗;
l 異步處理:多應用對消息隊列中同一消息進行處理,應用間併發處理消息,相比串行處理,減小處理時間;
l 限流削峯:普遍應用於秒殺或搶購活動中,避免流量過大致使應用系統掛掉的狀況;
l 消息驅動的系統:系統分爲消息隊列、消息生產者、消息消費者,生產者負責產生消息,消費者(可能有多個)負責對消息進行處理;
下面詳細介紹上述四個場景以及消息隊列如何在上述四個場景中使用:服務器
2.1 異步處理
具體場景:用戶爲了使用某個應用,進行註冊,系統須要發送註冊郵件並驗證短信。對這兩個操做的處理方式有兩種:串行及並行。
(1)串行方式:新註冊信息生成後,先發送註冊郵件,再發送驗證短信;網絡
在這種方式下,須要最終發送驗證短信後再返回給客戶端。併發
(2)並行處理:新註冊信息寫入後,由發短信和發郵件並行處理;異步
在這種方式下,發短信和發郵件需處理完成後再返回給客戶端。分佈式
假設以上三個子系統處理的時間均爲50ms,且不考慮網絡延遲,則總的處理時間:
串行:50+50+50=150ms
並行:50+50 = 100ms網站
若使用消息隊列:ui
並在寫入消息隊列後當即返回成功給客戶端,則總的響應時間依賴於寫入消息隊列的時間,而寫入消息隊列的時間自己是能夠很快的,基本能夠忽略不計,所以總的處理時間相比串行提升了2倍,相比並行提升了一倍;索引
2.2 應用耦合
具體場景:用戶使用QQ相冊上傳一張圖片,人臉識別系統會對該圖片進行人臉識別,通常的作法是,服務器接收到圖片後,圖片上傳系統當即調用人臉識別系統,調用完成後再返回成功,以下圖所示:
該方法有以下缺點:
人臉識別系統被調失敗,致使圖片上傳失敗;
延遲高,須要人臉識別系統處理完成後,再返回給客戶端,即便用戶並不須要當即知道結果;
圖片上傳系統與人臉識別系統之間互相調用,須要作耦合;
若使用消息隊列:
客戶端上傳圖片後,圖片上傳系統將圖片信息如uin、批次寫入消息隊列,直接返回成功;而人臉識別系統則定時從消息隊列中取數據,完成對新增圖片的識別。
此時圖片上傳系統並不須要關心人臉識別系統是否對這些圖片信息的處理、以及什麼時候對這些圖片信息進行處理。事實上,因爲用戶並不須要當即知道人臉識別結果,人臉識別系統能夠選擇不一樣的調度策略,按照閒時、忙時、正常時間,對隊列中的圖片信息進行處理。
2.3 限流削峯
具體場景:購物網站開展秒殺活動,通常因爲瞬時訪問量過大,服務器接收過大,會致使流量暴增,相關係統沒法處理請求甚至崩潰。而加入消息隊列後,系統能夠從消息隊列中取數據,至關於消息隊列作了一次緩衝。
該方法有以下優勢:
請求先入消息隊列,而不是由業務處理系統直接處理,作了一次緩衝,極大地減小了業務處理系統的壓力;
隊列長度能夠作限制,事實上,秒殺時,後入隊列的用戶沒法秒殺到商品,這些請求能夠直接被拋棄,返回活動已結束或商品已售完信息;
2.4 消息驅動的系統
具體場景:用戶新上傳了一批照片, 人臉識別系統須要對這個用戶的全部照片進行聚類,聚類完成後由對帳系統從新生成用戶的人臉索引(加快查詢)。這三個子系統間由消息隊列鏈接起來,前一個階段的處理結果放入隊列中,後一個階段從隊列中獲取消息繼續處理。
該方法有以下優勢:
避免了直接調用下一個系統致使當前系統失敗;
每一個子系統對於消息的處理方式能夠更爲靈活,能夠選擇收到消息時就處理,能夠選擇定時處理,也能夠劃分時間段按不一樣處理速度處理;
消息隊列包括兩種模式,點對點模式(point to point, queue)和發佈/訂閱模式(publish/subscribe,topic)。
3.1 點對點模式
點對點模式下包括三個角色:
消息隊列
發送者 (生產者)
接收者(消費者)
消息發送者生產消息發送到queue中,而後消息接收者從queue中取出而且消費消息。消息被消費之後,queue中再也不有存儲,因此消息接收者不可能消費到已經被消費的消息。
點對點模式特色:
每一個消息只有一個接收者(Consumer)(即一旦被消費,消息就再也不在消息隊列中);
發送者和接收者間沒有依賴性,發送者發送消息以後,無論有沒有接收者在運行,都不會影響到發送者下次發送消息;
接收者在成功接收消息以後需向隊列應答成功,以便消息隊列刪除當前接收的消息;
3.2 發佈/訂閱模式
發佈/訂閱模式下包括三個角色:
角色主題(Topic)
發佈者(Publisher)
訂閱者(Subscriber)
發佈者將消息發送到Topic,系統將這些消息傳遞給多個訂閱者。
發佈/訂閱模式特色:
每一個消息能夠有多個訂閱者;
發佈者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者以後,才能消費發佈者的消息。
爲了消費消息,訂閱者須要提早訂閱該角色主題,並保持在線運行;
四種經常使用的消息隊列(RabbitMQ/ActiveMQ/RocketMQ/Kafka)的主要特性、優勢、缺點,請查看【廣州校區】+ 【原創】分佈式消息隊列【下】