Swoole生命周期

PHP底層工作原理

PHP體系架構(gòu)

PHP的相關(guān)進(jìn)程是隨著Web服務(wù)器如Apache、Nginx等的啟動而運(yùn)行的慨畸,這里以Apache為例簡要梳理下流程:

PHP中客戶端和服務(wù)器的交互
  1. PHP通過mod_php.so擴(kuò)展和Apache建立聯(lián)系,具體來說是SAPI服務(wù)器應(yīng)用程序編程接口。

當(dāng)Apache服務(wù)器啟動后陨献,PHP解釋程序也隨之啟動,PHP啟動的過程分為兩步:

  • 初始化環(huán)境變量懂更,這些環(huán)境變量將在SAPI生命周期中發(fā)生作用眨业。
    PHP解釋程序啟動后,會調(diào)用各個(gè)擴(kuò)展的MINIT方法即“模塊初始化”沮协,從而使擴(kuò)展切換到可用狀態(tài)龄捡。MINIT指的是,每個(gè)擴(kuò)展模塊都定義了一組函數(shù)慷暂、類庫等用于處理其它請求聘殖。
  • 生成只針對當(dāng)前請求的變量設(shè)置
    當(dāng)客戶端的請求發(fā)生時(shí),SAPI層將控制權(quán)交給PHP層行瑞。于是奸腺,PHP設(shè)置了用于回復(fù)本次請求所需的環(huán)境變量,用來存放執(zhí)行過程中產(chǎn)生的變量名和值血久。PHP調(diào)用各個(gè)擴(kuò)展模塊的RINIT方法即請求初始化突照。經(jīng)典的案例使Session模塊的RINIT方法,如果在php.ini中啟用了Session擴(kuò)展模塊氧吐,那么在調(diào)用該模塊的RINIT時(shí)就會初始化$_SESSION全局變量讹蘑,并將相關(guān)內(nèi)容讀取末盔。RINIT方法可看作是一個(gè)準(zhǔn)備過程,在程序執(zhí)行之間就會自動啟動衔肢。

如同PHP啟動一樣庄岖,PHP的關(guān)閉也分為兩個(gè)步驟

  • 一旦腳本執(zhí)行完畢,無論是執(zhí)行到文件末尾還是使用exitdie函數(shù)中止角骤。PHP都會啟動清理程序隅忿,清理程序會按順序調(diào)用各個(gè)擴(kuò)展模塊的RSHUTDOWN方法,RSHUTDOWN方法用來清理程序運(yùn)行時(shí)產(chǎn)生的符號表邦尊,也就是對每個(gè)變量調(diào)用unset函數(shù)背桐。
  • 當(dāng)所有的請求都處理完畢后,SAPI也準(zhǔn)備關(guān)閉了蝉揍。此時(shí)链峭,PHP會調(diào)用每個(gè)擴(kuò)展模塊的MSHUTDOWN方法,這是各個(gè)擴(kuò)展模塊最后一次釋放內(nèi)存的機(jī)會又沾。
  1. PHP中共有三個(gè)模塊:PHP內(nèi)核弊仪、Zend引擎、擴(kuò)展層
PHP核心
  • PHP內(nèi)核:用來處理請求杖刷、文件流励饵、錯(cuò)誤處理等相關(guān)操作
  • Zend引擎:將PHP源文件轉(zhuǎn)換成機(jī)器語言,并在Zend虛擬機(jī)上運(yùn)行滑燃。
  • 擴(kuò)展層:是一組函數(shù)役听、類庫和流

PHP使用這個(gè)三個(gè)模塊來執(zhí)行特定的操作,如使用MySQL擴(kuò)展來連接MySQL數(shù)據(jù)表窘。

  1. 當(dāng)Zend引擎執(zhí)行程序時(shí)可能會需要連接若干擴(kuò)展典予,此時(shí)Zend引擎會將控制權(quán)交給擴(kuò)展,等處理完特定任務(wù)后再返還乐严。
  2. Zend引擎將運(yùn)行結(jié)果返回給PHP內(nèi)核瘤袖,PHP內(nèi)核將結(jié)果傳遞給SAPI,最終通過Web服務(wù)器輸出到瀏覽器昂验。

PHP腳本運(yùn)行流程

PHP作為Swoole的宿主孽椰,下圖是以CLI命令行下執(zhí)行一個(gè)PHP腳本文件時(shí)的完整流程:

PHP生命周期

SAPI是PHP給外部環(huán)境執(zhí)行PHP內(nèi)核提供的統(tǒng)一接口,常見有三種:CLI凛篙、PHP-FPM黍匾、MOD_PHP。

以PHP-FPM為例呛梆,將PHP運(yùn)行周期的關(guān)鍵步驟提热裱摹:

PHP-FPM
  1. 初始化
    PHP引擎初始化公用配置,讀取.ini配置文件填物,加載zend引擎纹腌。

  2. MINIT
    執(zhí)行PHP各個(gè)擴(kuò)展模塊的MINIT(模塊初始化)方法后霎终,常駐在PHP-FPM進(jìn)程中,等待處理請求升薯。

  3. RINIT
    當(dāng)請求過來后莱褒,調(diào)用PHP各個(gè)擴(kuò)展模塊的RINIT(請求初始化)方法進(jìn)行請求內(nèi)數(shù)據(jù)的初始化,如超全局變量和模塊數(shù)據(jù)的初始化等操作涎劈。

  4. 執(zhí)行PHP腳本
    加載PHP腳本文件广凸,進(jìn)行詞法分析、語法分析蛛枚、生成Opcode中間代碼谅海,然后交給Zend虛擬機(jī),暫存執(zhí)行結(jié)果蹦浦。


    解釋型語言PHP的執(zhí)行流程
  5. RSHUTDOWN
    在結(jié)果返回給PHP-FPM之前扭吁,會調(diào)用PHP各個(gè)擴(kuò)展模塊的RSHUTDOWN(請求關(guān)閉)方法進(jìn)行數(shù)據(jù)的回收,Zend虛擬機(jī)會關(guān)閉打開的數(shù)據(jù)流盲镶,進(jìn)行內(nèi)存釋放等操作侥袜,然后把暫存的執(zhí)行結(jié)果flush輸出。

  6. MSHUTDOWN
    當(dāng)重啟PHP-FPM時(shí)會調(diào)用PHP各個(gè)擴(kuò)展模塊的MSHUTDOWN(模塊關(guān)閉)方法溉贿,執(zhí)行關(guān)閉Zend引擎等操作枫吧。

通過以上流程可以發(fā)現(xiàn)PHP-FPM中每個(gè)請求都是在執(zhí)行第3~5步,Opcode緩存是將第4步的詞法分析顽照、語法分析、生成Opcode中間代碼等幾個(gè)操作給緩存起來闽寡,從而達(dá)到加速的目的代兵。

Opcode

既然每個(gè)請求都是獨(dú)立的,那么能不能進(jìn)行數(shù)據(jù)共享呢爷狈?由于在MINIT模塊初始化時(shí)數(shù)據(jù)是常駐在PHP-FPM進(jìn)程中的植影,所有是可以實(shí)現(xiàn)的,例如比較典型的.ini配置文件是放在這一步的涎永。另外每個(gè)請求都能夠獨(dú)立釋放內(nèi)存思币,總體上是安全的,但也是有問題的羡微,很有可能在擴(kuò)展層就存在內(nèi)存泄漏谷饿。所以PHP-FPM提供max_request來重啟PHP-FPM,達(dá)到完全釋放內(nèi)存的目的妈倔。

Swoole的生命周期

分析了PHP的基本執(zhí)行流程后博投,Swoole是在哪一步執(zhí)行的呢?首先盯蝴,Swoole運(yùn)行有個(gè)前提條件:必須在CLI命令行模式下執(zhí)行毅哗。Swoole在PHP執(zhí)行流程的第4步執(zhí)行PHP腳本時(shí)就接管了PHP听怕,進(jìn)入了Swoole的生命周期。

Swoole的生命周期以多進(jìn)程模式為例虑绵,具體流程如下:

Swoole執(zhí)行流程
  1. 初始化
    創(chuàng)建Manager管理進(jìn)程尿瞭,創(chuàng)建Worker工作子進(jìn)程,監(jiān)聽所有TCP/UDP端口翅睛,監(jiān)聽定時(shí)器Timer声搁。
  2. onStart
    onStart回調(diào)函數(shù)是在Master主進(jìn)程中執(zhí)行的,和Worker工作子進(jìn)程的onWorkStart是并行的宏所,并沒有先后之分酥艳。在此回調(diào)函數(shù)中強(qiáng)烈要求只做Log記錄和進(jìn)程名設(shè)置操作,不要做業(yè)務(wù)邏輯爬骤。因?yàn)闃I(yè)務(wù)邏輯代碼的錯(cuò)誤將直接導(dǎo)致Master主進(jìn)程Crash崩潰充石,進(jìn)而讓整個(gè)Swoole服務(wù)器無法對外提供服務(wù)。
  3. onReceive
    客戶端請求的數(shù)據(jù)到達(dá)時(shí)會調(diào)用onReceive函數(shù)霞玄,進(jìn)行業(yè)務(wù)邏輯處理輸出結(jié)果骤铃。客戶端發(fā)送的多次請求坷剧,服務(wù)端是可以一次性接收的惰爬,所以會發(fā)現(xiàn)一個(gè)問題是onReceive接收的數(shù)據(jù)會非常大。
  4. onWorkerStop
    Worker工作子進(jìn)程退出時(shí)回調(diào)onWorkerStop函數(shù)惫企。
  5. onShutDown
    Swoole服務(wù)停止時(shí)回調(diào)onShutDown函數(shù)撕瞧,然后繼續(xù)PHP-FPM的第5~6步,最后退出PHP的生命周期狞尔。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丛版,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子偏序,更是在濱河造成了極大的恐慌页畦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件研儒,死亡現(xiàn)場離奇詭異豫缨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)端朵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門好芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冲呢,你說我怎么就攤上這事栓撞。” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵瓤湘,是天一觀的道長瓢颅。 經(jīng)常有香客問我,道長弛说,這世上最難降的妖魔是什么挽懦? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮木人,結(jié)果婚禮上信柿,老公的妹妹穿的比我還像新娘。我一直安慰自己醒第,他們只是感情好渔嚷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布稠曼。 她就那樣靜靜地躺著形病,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霞幅。 梳的紋絲不亂的頭發(fā)上漠吻,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音司恳,去河邊找鬼途乃。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扔傅,可吹牛的內(nèi)容都是我干的耍共。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼猎塞,長吁一口氣:“原來是場噩夢啊……” “哼试读!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邢享,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鹏往,失蹤者是張志新(化名)和其女友劉穎淡诗,沒想到半個(gè)月后骇塘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡韩容,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年款违,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片群凶。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡插爹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赠尾,我是刑警寧澤力穗,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站气嫁,受9級特大地震影響当窗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寸宵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一崖面、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梯影,春花似錦巫员、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至救军,卻和暖如春财异,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唱遭。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工戳寸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拷泽。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓疫鹊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親司致。 傳聞我的和親對象是個(gè)殘疾皇子拆吆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 參考資料 官方網(wǎng)站 https://www.swoole.com/page/download PHP沒有像Pyth...
    JunChow520閱讀 2,951評論 0 6
  • 進(jìn)程 什么是進(jìn)程 進(jìn)程Process是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動,是系統(tǒng)分配資源和調(diào)度的基本單位...
    JunChow520閱讀 2,037評論 2 9
  • 前文再續(xù)脂矫,就書接上一回枣耀,隨著與Server、TCP庭再、Protocol的邂逅捞奕,Swoole終于迎來了自己的故事,今天...
    蝸牛淋雨閱讀 1,735評論 1 14
  • 原文github地址 1.PHP概述 1.1 PHP的歷史發(fā)展 1995年由Lerdorf創(chuàng)建PHP拄轻,高級腳本語言...
    10xjzheng閱讀 1,519評論 0 2
  • 并發(fā)IO問題一直是服務(wù)器端編程中的技術(shù)難題颅围,從最早的同步阻塞直接Fork進(jìn)程,到Worker進(jìn)程池/線程池恨搓,到現(xiàn)在...
    零一間閱讀 1,714評論 1 34