1. 程式人生 > >PHP訊息佇列實現及應用:訊息佇列概念介紹

PHP訊息佇列實現及應用:訊息佇列概念介紹

 

在網際網路專案開發者經常會遇到『給使用者群發簡訊』、『訂單系統有大量的日誌需要記錄』或者在秒殺業務的時候伺服器無法承受瞬間併發的壓力。 
這種情況下,我們怎麼保證系統正常有效的執行呢?

這個時候,我們可以引入一個叫『訊息佇列』的概念來解決上面的需求。

訊息佇列的概念、原理和場景

在高併發的時候,程式往往無法做到及時的處理。我們引入一箇中間的系統,來進行分流和減壓。 
所以從本質上講:訊息佇列就是一個佇列結構的中介軟體。也就是說,你把訊息和內容放入這個容器之後就可以直接返回,不用等它後期處理的結果。另外會有一個程式,讀取這些資料並按照順序處理。

1、佇列結構的中介軟體
2、訊息放入後,不必立即處理
3、由訂閱者/消費者按順序處理

也就是說:當遇到一個比較大或者耗時比較長的環節的時候,而同時你的業務又不需要立即知道這個環節的結果,使用訊息佇列是好的選擇。

核心結構如下面: 
這裡寫圖片描述

訊息佇列 適用場景

一、資料需要冗餘的時候 
比如訂單系統中,後續需要進行資料的轉換和記錄。訊息佇列可以把這些資料持久化的儲存在佇列中,然後由訂單後期處理程式進行處理,處理完成之後再把這條記錄從佇列中刪除。

二、系統的解耦 
訊息佇列解決了2套系統之間深度耦合的問題。 
使用訊息佇列後,入隊的系統和出隊的系統沒有直接的關係。 
入隊系統和出隊系統,其中一個崩潰之後不會影響另外一個的正常執行。

三、流量削峰 
就是秒殺和搶購的時候,會出現明顯的流量劇增,對伺服器的壓力非常大。 
實際專案開發中,配合快取來使用訊息佇列,一種很好的方案。

四、非同步通訊 
訊息佇列本身就實現了程式的非同步操作,因此只要適合於非同步的場景都可以使用訊息佇列

五、擴充套件性 
比如訂單系統,訂單入隊之後,後期或許還有財務系統處理,但是如果還要加一個配貨系統。 
只需要讓這個配貨系統 訂閱這個 訊息佇列 即可。

六、排序保證 
在有些場景下,資料的處理順序是非常重要的,佇列本身就可以做成單執行緒的單進單出的系統。 
從而有效的保證資料按照順序進行處理。

佇列的最主要用途是非同步任務和通訊兩個方面。

非同步的思路主要用來緩解瞬間壓力、耗時操作、並行任務等。
1. 緩解瞬間壓力:若系統每秒處理能力是100請求,而最高峰值可能達到每秒1000請求,若不採用佇列,很有可能會出現服務不可用或者長時間等待。此時可以用佇列將未能成功執行的請求放入佇列,順序執行,直到所有請求都被處理。
2. 耗時操作:如@loki 提到的縮圖生成。
3. 並行任務:如在發貼後分發通知所有的好友。

通訊的思路主要用來解決在不同的獨立模組或者系統之間相互同步資料、通知執行某些操作等。

常見 佇列實現 的優缺點

佇列介質:

Mysql:可靠性高、易實現、速度慢
Redis:速度快,單條大訊息包時效率低
訊息系統:專業性強、可靠,學習成本高(比如:RabbtiMQ)

訊息處理的觸發機制:

死迴圈方式讀取:易實現,故障時無法及時恢復;
定時任務:壓力均分,有處理量上限。(最大的缺陷:定位任務時間的間隔和處理的資料需要精準把握,不能上一個任務還沒有處理完成,下一個認為就已經啟動了)

守護程序:類似於PHP-FPM和PHP-CGI,需要shell知識