iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 5
1
Software Development

從零開始土炮MQ系列 第 5

三、Queue 的應用(1) - 生產者與消費者模型 (producer-consumers pattern)

  • 分享至 

  • xImage
  •  

3.1 生產者與消費者模型 (producer-consumers pattern)

依慣例,在說明生產者與消費者模型之前,先用一個現實的情境來舉例。

A 公司推出新的 3C 產品,預計會有兩、三波的搶購熱潮。

所以它找了三間代工廠,幫它預先生產了五萬組商品,放在集貨倉庫之中。後續持續生產三萬組。
如它預期,一上巿果然引起搶購熱潮,庫存在幾天內,就將商品售完。消費者因為沒有現貨,只能等待到貨。

A 公司評估銷售後,這情況,決定新增一間代工廠,追加兩萬組商品。
那知好景不長,B 公司推出殺手級的商品,大部份旳消費者轉向購買 B 公司的商品。
A 公司只能將緊急中止新代工廠的訂單,待原本代工廠完成原本的訂單後,停止生產。而己經生產的商品,持續放在倉庫中,等待消費者來購買。

在上面的故事中,我們看到三個角色。這三個角色動作的時間點與作用均不相同。

  • 代工廠:在銷售前的預生產;銷售中的持續生產;最後完成訂單後,停止生產。
  • 集貨倉庫:商品的存放區。
  • 消費者:銷售後的購買行為。

https://ithelp.ithome.com.tw/upload/images/20190921/20107551RN0lICuSr4.png

其中,代工廠作為生產者,負責產生資源(商品)。集貨倉庫可視為 Queue,負責資源的暫存緩衝與資源調派。消費者,就負責把資源取走、使用。

而且,在實例中,我們可以看到一些特性。

  • 解耦

    代工廠與消費者中間,透過集貨倉庫,將兩端隔離。不會發生消費者直接衝到代工廠內,大喊我要商品,快給我。或是代工廠衝到消費者面對,大喊給我買。

    透過集貨倉庫,代工廠不會知道有那些消費者會來購買商品。相同的,消費者也不知道商品是那些代工廠所生產的。

    A 公司決定更換代工廠,對消費者完全沒影響。消費者的身分,由個人購買更換為公司行號大量購買,對代工廠也沒有影響。因為兩者而言,它們所聚焦的重點在於商品本身,而非其他對象

  • 並發

    以代工廠的角度,代工廠將生產出來的商品放到集貨倉庫,完全不需考慮商品的銷售情況。A 公司可以依商品的銷售情況,增減代工廠的數量。

    以消費者的角度:如果商品本身很受歡迎,有購買意願的消費者數量就會增加。反之,如果沒有購買意願,消費者的數量就會減少。而不需理會代工廠產生的商品數量。

  • 速率不均

    在上面的例子中,因為商品生產的速度比較慢,所在代工廠在銷售之前,就預先生產五萬商品。但是因為消費者購買速率遠大於生產速度,造成售完的情況。

    雖然,A 公司預估預產商品錯誤有誤,讓商品出現售完的情況。偶後,因為滯銷的情況,讓後面生商出來的商品只能存放於倉庫,等待慢慢銷售。

    但換個角度,正是因為有集貨倉庫,讓商品可以預生產與滯銷的週轉空間。

將上面提到的三個特性,試著以軟體系統的角度解讀。

  • 解耦

    若將生產者與消費者分別視為兩個不同的 A、B 模組。

    當發生 A 模組直接調用 B 模組的方法,兩者之間就建立起耦合關係。若將來 B 模組的方法變更,就可能影響到 A。

    利用 Queue 將兩者隔離,讓兩者依賴於 Queue,A、B 模組之間沒有直接依賴,解決其耦合關係。

  • 並發

    系統可以依據最重要資源數量,動態決定是增加產生資源的生產者數量,還是減少處理資源的消費者數量。

  • 速率不均

    有時資料的產生,可能是一瞬間突然湧進,利用 Queue 的緩衝特性,讓來不及處理的資料可以先暫存下來,等後面產生資料的速度慢下來後,可以處理完成。

所以,Queue 的使用情境,可以彙整為以下幾點。

  • 速率不對等:產生資料的速度與處理資料的速度不同。
  • 避免高耦合:不希望產生資料的模組與處理資料的模組直接相互存取,避免高耦合。
  • 並發性處理:同時可以多線程的產生資料,或是處理資料。
  • 資源的調配:當 Queue 塞滿資源時,要讓生產端得知;不存在任何資料時,則需處理端知道。

因為這種需要處理的問題,一再反覆出現。當其具有規則性旳部份,統整為一個模型,就是生產者與消費者模型(producer-consumers pattern)

同時並發、速率不均的因素,如何有效管理資源放入或取出的正確性,就變得十分的重要。為此,對 Queue 有以下的要求。

  • 當 Queue 己填滿資源,就要阻擋生產者持續產生資源,避免持續填入資源。
  • 當 Queue 內部清空時,也要阻擋消費者繼續取得資源。

當符合兩點特性的 Queue ,稱為阻塞佇列 (BlockQueue) 。

接下來,介紹 LockSemaphoreBlackingQueue 三種同步機制,確保 Queue 內的共用資源的正確性。


上一篇
二、基本的 queue(3) - Linked List
下一篇
三、Queue 的應用(2) - 以 Lock 保護共用資源
系列文
從零開始土炮MQ30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言