生產者消費者模式 php 【轉】

在工做中經常聽到某某大牛之間的交談會涉及到,xx消費者啊啥的,到底什麼大牛之間講的是什麼? 
這篇文章主要解決三個問題: 
1.到底什麼是生產者和消費者,以及它們之間的故事 
2.它們之間靠什麼交流 
3.應用場景php

正文

1、什麼是生產者和消費者,以及它們之間的故事

在實際的程序開發中,會常常碰到這樣的狀況:小a模塊負責生產數據,這些數據由另一個模塊負責處理。產生數據的模塊,就形象地稱爲生產者;而處理數據的模塊,就稱爲消費者。redis

單單抽象出生產者和消費者,還夠不上是生產者/消費者模式。該模式還須要有一個緩衝區處於生產者和消費者之間,做爲一箇中介。生產者把數據放入緩衝區,而消費者從緩衝區取出數據。大概的結構以下圖。swoole

這裏寫圖片描述

能夠這麼理解,你(生產者)須要寫信寄給基友,你先放到郵箱(緩衝區),郵遞員(消費者)從郵箱取信進行派送(數據處理)。併發

那麼有同窗問了,好好的生產者和消費者直接溝通不就行了,搞出一個緩衝區是作甚? 
其實這是有內涵(優勢)的:異步

解耦函數

假設生產者和消費者都是兩個類,若是直接讓生產者調消費者的類的方法,勢必會使其依賴於消費者的類方法,萬一消費者的消費方式改變(函數改掉啦)那麼生產者也要改。好了,代碼耦合了。高併發

那麼若是有了緩衝區就不同了,兩個都依賴於緩衝區,緩衝區只起到緩衝數據做用,一邊存一邊取,互不關聯也不依賴。性能

ps:你寫信直接交給郵遞員,萬一郵遞員換了,那你不是還要從新認識一下,還要關心是否是真的郵遞員。那若是是放郵箱的話,郵遞員是誰和你半毛錢關係沒有。.net

支持併發設計

生產者直接調消費者某個方法有個弊端:因爲函數是同步的,也能夠說是阻塞的,消費者沒返回以前,生產者只能一直等着,萬一消費者處理的又很慢,那生產者空閒着就浪費了。 
使用了生產者/消費者模式以後,生產者和消費者能夠是兩個獨立的併發主體。生產者把製造出來的數據往緩衝區一丟,就能夠再去生產下一個數據。基本上不用依賴消費者的處理速度。

ps:若是沒郵箱,你就要站在等郵遞員來,想必這是坑爹的一件事。

支持生產消費者忙閒不均

緩衝區還有另外一個好處。若是製造數據的速度時快時慢,緩衝區的好處就體現出來了。當數據製造快的時候,消費者來不及處理,未處理的數據能夠暫時存在緩衝區中。等生產者的製造速度慢下來,消費者再慢慢處理掉。

ps:萬一今天是情人節啥的,寄信的人特別多,郵遞員一回只能帶100封,那麼多餘100封的部分就能夠放在郵箱,等處理好100封后再回頭取,繼續處理。

它們之間靠什麼交流

那麼生產者和消費者之間怎麼交流呢?固然是經過數據單元交流的。何謂數據單元捏?簡單地說,每次生產者放到緩衝區的,就是一個數據單元;每次消費者從緩衝區取出的,也是一個數據單元。

ps:寄信,信就是數據單元

那麼數據單元涉及到一個很關鍵的問題,就是數據粒度的問題。 
有時出於性能等因素的考慮,也可能會把N個業務對象打包成一個數據單元。那麼,這個N該如何取值就是顆粒度的考慮了。顆粒度的大小是有講究的。太大 的顆粒度可能會形成某種浪費;過小的顆粒度可能會形成性能問題。顆粒度的權衡要基於多方面的因素,以及一些經驗值的考量。

ps:仍是拿寄信的例子。若是顆粒度太小(好比設定爲1),那郵遞員每次只取出1封信。若是信件多了,那就得來回跑好多趟,浪費了時間。 
若是顆粒度太大(好比設定爲100),那寄信的人得等到湊滿100封信纔拿去放入郵筒。假如平時不多寫信,就得等上好久,會很不爽滴~

應用場景

那麼在php中哪些地方會用到呢,或者說哪些地方會看到別人用到生產者和消費者模式?這裏簡單講幾個:

swoole

對,你沒看錯,就是swoole。那麼swoole實際上是有使用了這個設計的模式,業務邏輯(生產者)將數據單元經過swoole的send函數弄到swoole的一個緩衝區之間,經過work進程進行分發,task進程(消費者)進行消費。

耗時操做的異步處理

當「耗時操做「遇到了」高併發「,若是不採起一點措施,卡慢崩會慢慢到來,此時能夠將要處理的耗時操做的相關信息(數據單元)經過業務邏輯[生產者]push到redis隊列中(redis只是舉例),在經過跑一個腳本的進程[消費者]進行pop出數據單元進行處理。

 

轉載自

http://blog.csdn.net/u011957758/article/details/51138707

相關文章
相關標籤/搜索