天天看點

PHP進階程式設計之消息隊列

中國廣東省深圳市龍華新區民治街道溪山美地

518131

+86 13113668890

+86 755 29812080

版權聲明

轉載請與作者聯系,轉載時請務必标明文章原始出處和作者資訊及本聲明。

PHP進階程式設計之消息隊列

文檔出處:

<a href="http://netkiller.github.io/" target="_top">http://netkiller.github.io</a>

<a href="http://netkiller.sourceforge.net/" target="_top">http://netkiller.sourceforge.net</a>

PHP進階程式設計之消息隊列

讀者群:128659835 請注明“讀者”

2015-10-20

摘要

我的系列文檔

<a href="http://netkiller.github.io/architect/index.html" target="_top">netkiller architect 手劄</a>

<a href="http://netkiller.github.io/developer/index.html" target="_top">netkiller developer 手劄</a>

<a href="http://netkiller.github.io/php/index.html" target="_top">netkiller php 手劄</a>

<a href="http://netkiller.github.io/python/index.html" target="_top">netkiller python 手劄</a>

<a href="http://netkiller.github.io/testing/index.html" target="_top">netkiller testing 手劄</a>

<a href="http://netkiller.github.io/cryptography/index.html" target="_top">netkiller cryptography 手劄</a>

<a href="http://netkiller.github.io/linux/index.html" target="_top">netkiller linux 手劄</a>

<a href="http://netkiller.github.io/debian/index.html" target="_top">netkiller debian 手劄</a>

<a href="http://netkiller.github.io/centos/index.html" target="_top">netkiller centos 手劄</a>

<a href="http://netkiller.github.io/freebsd/index.html" target="_top">netkiller freebsd 手劄</a>

<a href="http://netkiller.github.io/shell/index.html" target="_top">netkiller shell 手劄</a>

<a href="http://netkiller.github.io/security/index.html" target="_top">netkiller security 手劄</a>

<a href="http://netkiller.github.io/www/index.html" target="_top">netkiller web 手劄</a>

<a href="http://netkiller.github.io/monitoring/index.html" target="_top">netkiller monitoring 手劄</a>

<a href="http://netkiller.github.io/storage/index.html" target="_top">netkiller storage 手劄</a>

<a href="http://netkiller.github.io/mail/index.html" target="_top">netkiller mail 手劄</a>

<a href="http://netkiller.github.io/docbook/index.html" target="_top">netkiller docbook 手劄</a>

<a href="http://netkiller.github.io/project/index.html" target="_top">netkiller project 手劄</a>

<a href="http://netkiller.github.io/database/index.html" target="_top">netkiller database 手劄</a>

<a href="http://netkiller.github.io/postgresql/index.html" target="_top">netkiller postgresql 手劄</a>

<a href="http://netkiller.github.io/mysql/index.html" target="_top">netkiller mysql 手劄</a>

<a href="http://netkiller.github.io/nosql/index.html" target="_top">netkiller nosql 手劄</a>

<a href="http://netkiller.github.io/ldap/index.html" target="_top">netkiller ldap 手劄</a>

<a href="http://netkiller.github.io/network/index.html" target="_top">netkiller network 手劄</a>

<a href="http://netkiller.github.io/cisco/index.html" target="_top">netkiller cisco ios 手劄</a>

<a href="http://netkiller.github.io/h3c/index.html" target="_top">netkiller h3c 手劄</a>

<a href="http://netkiller.github.io/multimedia/index.html" target="_top">netkiller multimedia 手劄</a>

<a href="http://netkiller.github.io/perl/index.html" target="_top">netkiller perl 手劄</a>

<a href="http://netkiller.github.io/radio/index.html" target="_top">netkiller amateur radio 手劄</a>

<a href="http://netkiller.github.io/devops/index.html" target="_top">netkiller devops 手劄</a>

目錄

<a href="http://netkiller.github.io/journal/php.mq.html#what">1. 什麼是消息隊列</a>

<a href="http://netkiller.github.io/journal/php.mq.html#why">2. 為什麼使用消息隊列</a>

<a href="http://netkiller.github.io/journal/php.mq.html#where">3. 什麼場合使用消息隊列</a>

<a href="http://netkiller.github.io/journal/php.mq.html#when">4. 什麼時候使用消息隊列</a>

<a href="http://netkiller.github.io/journal/php.mq.html#who">5. 誰負責處理消息隊列</a>

<a href="http://netkiller.github.io/journal/php.mq.html#how">6. 怎麼實作消息隊列架構</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53181008">6.1. 守護程序</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53185328">6.2. 消息隊列協定</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53188688">6.3. 消息隊列處理</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53193760">6.4. 測試</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53197264">7. 總結</a>

<a href="http://netkiller.github.io/journal/php.mq.html#idp53198688">8. 延伸閱讀</a>

消息隊列(英語:message queue)是一種程序間通信或同一程序的不同線程間的通信方式

消息隊列技術是分布式應用間交換資訊的一種技術。消息隊列可駐留在記憶體或磁盤上,隊列存儲消息直到它們被應用程式讀出。通過消息隊列,應用程式可獨立地執行,它們不需要知道彼此的位置、或在繼續執行前不需要等待接收程式接收此消息。

你首先需要弄清楚,消息隊列與遠端過程調用的差別,在很多讀者咨詢我的時候,我發現他們需要的是rpc(遠端過程調用),而不是消息隊列。

消息隊列有同步或異步實作方式,通常我們采用異步方式使用消息隊列,遠端過程調用多采用同步方式。

mq與rpc有什麼不同? mq通常傳遞無規則協定,這個協定由使用者定義并且實作存儲轉發;而rpc通常是專用協定,調用過程傳回結果。

同步需求,遠端過程調用(prc)更适合你。

異步需求,消息隊列更适合你。

目前很多消息隊列軟體同時支援rpc功能,很多rpc系統也能異步調用。

消息隊列用來實作下列需求

存儲轉發

分布式事務

釋出訂閱

基于内容的路由

點對點連接配接

通常的做法,如果小的項目團隊可以有一個人實作,包括消息的推送,接收處理。如果大型團隊,通常是定義好消息協定,然後各自開發各自的部分, 例如一個團隊負責寫推送協定部分,另一個團隊負責寫接收與處理部分。

那麼為什麼我們不講消息隊列架構化呢?

架構化有幾個好處:

開發者不用學習消息隊列接口

開發者不需要關心消息推送與接收

開發者通過統一的api推送消息

開發者的重點是實作業務邏輯功能

下面是作者開發的一個soa架構,該架構提供了三種接口,分别是soap,restful,amqp(rabbitmq),了解了該架構思想,你很容易進一步擴充,例如增加xml-rpc, zeromq等等支援。

<a href="https://github.com/netkiller/soa" target="_top">https://github.com/netkiller/soa</a>

本文隻講消息隊列架構部分。

消息隊列架構是本地應用程式(指令行程式),我們為了讓他在背景運作,需要實作守護程序。

<a href="https://github.com/netkiller/soa/blob/master/bin/rabbitmq.php" target="_top">https://github.com/netkiller/soa/blob/master/bin/rabbitmq.php</a>

每個執行個體處理一組隊列,執行個體化需要提供三個參數,$queuename = '隊列名', $exchangename = '交換名', $routekey = '路由'

守護程序需要使用root使用者運作,運作後會切換到普通使用者,同僚建立程序id檔案,一邊程序停止的時候使用。

消息協定是一個數組,将數組序列化或者轉為json推送到消息隊列伺服器,這裡使用json格式的協定。

序列化後的協定

使用json格式是考慮到通用性,這樣推送端可以使用任何語言。如果不考慮相容,建議使用二進制序列化,例如msgpack效率更好。

消息隊列處理核心代碼

<a href="https://github.com/netkiller/soa/blob/master/system/rabbitmq.class.php" target="_top">https://github.com/netkiller/soa/blob/master/system/rabbitmq.class.php</a>

是以消息的處理在下面一段代碼中進行

public function loader($msg = null) 負責拆解協定,然後載入對應的類檔案,傳遞參數,運作方法,回報結果。

time 可以輸出程式運作所花費的時間,對于後期優化十分有用。

loader() 可以進一步優化,使用多線程每次調用loader将任務送出到線程池中,這樣便可以多線程處理消息隊列。

這裡隻給出了少量測試與示範程式,如有疑問請到渎者群,或者公衆号詢問。

該消息隊列架構還比較簡陋,但在生産環境已經運作很長一段時間,效果還是不錯的。同時降低了消息隊列的開發難度,開發者更多的時間是考慮業務邏輯的實作,而不用操心消息隊列本身的使用。

<a href="http://netkiller.github.io/journal/php.daemon.html" target="_top">php進階程式設計之守護程序</a>

<a href="http://netkiller.github.io/journal/php.thread.html" target="_top">php進階程式設計之多線程</a>