您好,登錄后才能下訂單哦!
如何進(jìn)行Swoole引擎原理的分析,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
過(guò)去半年使用PHP和Java兩種技術(shù)棧完成了一個(gè)游戲服務(wù)器項(xiàng)目。由于項(xiàng)目中有高頻的網(wǎng)絡(luò)請(qǐng)求,所以PHP技術(shù)棧嘗試使用Swoole引擎(基于事件的高性能異步并行網(wǎng)絡(luò)通信引擎)來(lái)完成部分游戲業(yè)務(wù)。
安裝swoole很簡(jiǎn)單,由于是國(guó)人做的項(xiàng)目,很多issue可以在官網(wǎng)文檔找到答案。安裝分兩種:
編譯安裝。直接去github或者gitee去下載官方的發(fā)行版,編譯安裝后,將so拓展寫入php.ini文件。
容器安裝。swoole引擎應(yīng)用廣泛,所以hub上有很多可用的容器,選擇需要的pull一下即可。
具體操作百度一下即可,網(wǎng)上相關(guān)內(nèi)容很多。
常駐內(nèi)存。傳統(tǒng) PHP框架或者單文件,在處理每個(gè)請(qǐng)求之前,都要做一遍加載框架文件、配置的操作,請(qǐng)求完成之后會(huì)釋放所有資源和內(nèi)存,無(wú)須擔(dān)心內(nèi)存泄漏。但是如果請(qǐng)求數(shù)量上升,并發(fā)很高的時(shí)候,快速創(chuàng)建資源,又馬上釋放,會(huì)導(dǎo)致 PHP 程序運(yùn)行效率急劇下降。而使用 Swoole 則沒有這個(gè)問(wèn)題:PHP的代碼加載到內(nèi)存后,擁有更長(zhǎng)的生命周期,這樣建立的數(shù)據(jù)庫(kù)連接和其他大的對(duì)象,不被釋放。每次請(qǐng)求只需要處理很少的代碼,而這些代碼只在第一次運(yùn)行時(shí),被 PHP 解析器編譯,駐留內(nèi)存。以后都是直接載入 OPCODE ,讓 Zend 引擎直接運(yùn)行。另外,之前PHP不能實(shí)現(xiàn)的,如數(shù)據(jù)庫(kù)連接池,緩存連接池都可以在Swoole引擎下實(shí)現(xiàn)。系統(tǒng)的運(yùn)行效率會(huì)大大提高。
快速開發(fā)。Swoole引擎提供了PHP語(yǔ)言的異步多線程服務(wù)器,異步TCP/UDP網(wǎng)絡(luò)客戶端,異步MySQL,異步Redis,數(shù)據(jù)庫(kù)連接池,AsyncTask,消息隊(duì)列,毫秒定時(shí)器,異步文件讀寫,異步DNS查詢。 Swoole內(nèi)置了Http/WebSocket服務(wù)器端/客戶端、Http2.0服務(wù)器端。
協(xié)程編程模式。Swoole4可以使用完全同步的代碼實(shí)現(xiàn)異步程序。PHP代碼無(wú)需額外增加任何關(guān)鍵詞,底層自動(dòng)進(jìn)行協(xié)程調(diào)度,實(shí)現(xiàn)異步IO。
Swoole運(yùn)行的流程圖如下:
Swoole中的線程或進(jìn)程
結(jié)構(gòu)圖如下:
Swoole引擎分為兩種模式:?jiǎn)尉€程模式和進(jìn)程模式。本文只討論進(jìn)程模式。具體兩者區(qū)別官方文檔中有說(shuō)明。
用于處理Swoole核心事件,比如來(lái)自客戶端的連接,本地通訊的管道。master進(jìn)程里有多個(gè)線程,每個(gè)線程運(yùn)行了一個(gè)epol函數(shù)的實(shí)例。(由于Worker進(jìn)程并不是由Master進(jìn)程fork出來(lái)的,所以可能會(huì)出現(xiàn)強(qiáng)行kill Master進(jìn)程后,Worker進(jìn)程依舊存在)
Swoole的主進(jìn)程是一個(gè)多線程的程序。其中有一組很重要的線程,稱之為Reactor線程。它就是真正處理TCP連接,收發(fā)數(shù)據(jù)的線程。 Swoole的主線程在Accept新的連接后,會(huì)將這個(gè)連接分配給一個(gè)固定的Reactor線程,并由這個(gè)線程負(fù)責(zé)監(jiān)聽此socket。在socket可讀時(shí)讀取數(shù)據(jù),并進(jìn)行協(xié)議解析,將請(qǐng)求投遞到Worker進(jìn)程。在socket可寫時(shí)將數(shù)據(jù)發(fā)送給TCP客戶端
Swoole中worker/task進(jìn)程都是由Manager進(jìn)程Fork并管理的。 子進(jìn)程結(jié)束運(yùn)行時(shí),manager進(jìn)程負(fù)責(zé)回收此子進(jìn)程,避免成為僵尸進(jìn)程。并創(chuàng)建新的子進(jìn)程 服務(wù)器關(guān)閉時(shí),manager進(jìn)程將發(fā)送信號(hào)給所有子進(jìn)程,通知子進(jìn)程關(guān)閉服務(wù) 服務(wù)器reload時(shí),manager進(jìn)程會(huì)逐個(gè)關(guān)閉/重啟子進(jìn)程
Swoole提供了完善的進(jìn)程管理機(jī)制,當(dāng)Worker進(jìn)程異常退出,如發(fā)生PHP的致命錯(cuò)誤、被其他程序誤殺,或達(dá)到max_request次數(shù)之后正常退出。主進(jìn)程會(huì)重新拉起新的Worker進(jìn)程。 Worker進(jìn)程內(nèi)可以像普通的apache+php或者php-fpm中寫代碼。不需要像Node.js那樣寫異步回調(diào)的代碼
Master內(nèi)的回調(diào)函數(shù):
onStart
onShutdown
Worker進(jìn)程內(nèi)的回調(diào)函數(shù)
onWorkerStart
onWorkerStop
onConnect
onClose
onReceive
onFinish
TaskWorker進(jìn)程內(nèi)的回調(diào)函數(shù)
onTask
onWorkerStart
Manager進(jìn)程內(nèi)的回調(diào)函數(shù)
onManagerStart
onManagerStop
可以理解為Reactor就是nginx,Worker就是php-fpm。Reactor線程異步并行地處理網(wǎng)絡(luò)請(qǐng)求,然后再轉(zhuǎn)發(fā)給Worker進(jìn)程中去處理。Reactor和Worker間通過(guò)UnixSocket進(jìn)行通信。
在php-fpm的應(yīng)用中,經(jīng)常會(huì)將一個(gè)任務(wù)異步投遞到Redis等隊(duì)列中,并在后臺(tái)啟動(dòng)一些php進(jìn)程異步地處理這些任務(wù)。Swoole提供的TaskWorker是一套更完整的方案,將任務(wù)的投遞、隊(duì)列、php任務(wù)處理進(jìn)程管理合為一體。通過(guò)底層提供的API可以非常簡(jiǎn)單地實(shí)現(xiàn)異步任務(wù)的處理。另外TaskWorker還可以在任務(wù)執(zhí)行完成后,再返回一個(gè)結(jié)果反饋到Worker。
Swoole的Reactor、Worker、TaskWorker之間可以緊密的結(jié)合起來(lái),提供更高級(jí)的使用方式。一個(gè)更通俗的比喻:假設(shè)Swoole應(yīng)用服務(wù)器是一個(gè)工廠,那Reactor就是銷售,接受客戶訂單。而Worker就是工人,當(dāng)銷售接到訂單后,Worker去工作生產(chǎn)出客戶要的東西。而TaskWorker可以理解為行政人員,可以幫助Worker干些雜事,讓W(xué)orker專心工作。
底層會(huì)為Worker進(jìn)程、TaskWorker進(jìn)程分配一個(gè)唯一的ID。不同的Worker和TaskWorker進(jìn)程之間可以通過(guò)sendMessage接口進(jìn)行通信。
Manager進(jìn)程:負(fù)責(zé)管理worker進(jìn)程,創(chuàng)建或回收
Worker進(jìn)程:游戲邏輯處理
taskWorker進(jìn)程:向客戶端發(fā)網(wǎng)絡(luò)包、關(guān)閉長(zhǎng)期不活躍的tcp連接
該項(xiàng)目開發(fā)階段使用的swoole引擎版本1.9.6,后來(lái)由于測(cè)試環(huán)境安裝成了4.3.2版本,所以嘗試業(yè)務(wù)代碼作調(diào)整。不過(guò)swoole的向下兼容很值得佩服的是,這過(guò)程中竟然只發(fā)現(xiàn)了一處代碼不兼容的問(wèn)題:是有關(guān)swoole_server的一項(xiàng)配置參數(shù),在原來(lái)版本采用了魔鬼數(shù)字進(jìn)行配置的,但是到新版本,這個(gè)數(shù)字沒有被宏定義,后來(lái)通過(guò)查看swoole源碼找到了宏定義組,然后修改了這處配置。(不過(guò)版本升級(jí)順利也是基于swoole的業(yè)務(wù)代碼比較少,所以僅供參考)
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。