亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁(yè) php框架 Workerman workerman源碼分析之啟動(dòng)過程詳解

workerman源碼分析之啟動(dòng)過程詳解

Nov 25, 2019 pm 01:57 PM
workerman

下面由workerman教學(xué)專欄跟大家介紹workerman原始碼分析之啟動(dòng)過程,希望對(duì)需要的朋友有幫助!

workerman源碼分析之啟動(dòng)過程詳解

#workerman

版本:3.1.8(linux)

模型:GatewayWorker(Worker模型可與之類比)

註:只貼出講解部分程式碼,出處以檔名形式給出,大家可自行查看

workerman最初只開發(fā)了Linux版本,win是後來(lái)增加的,基於命令列模式運(yùn)行(cli)。

多進(jìn)程模型

工作進(jìn)程,Master、Gateway和Worker,Gateway主要用於處理IO事件,保存客戶端連結(jié)狀態(tài),將資料處理請(qǐng)求發(fā)送給Worker等工作,Worker則是完全的業(yè)務(wù)邏輯處理,前者為IO密集型,後者為計(jì)算密集型,它們之間通過網(wǎng)絡(luò)通信,Gateway和Worker兩兩間註冊(cè)通信地址,所以非常方便的進(jìn)行分散式部署,如果業(yè)務(wù)處理量大可以單純的增加Worker服務(wù)。

workerman源碼分析之啟動(dòng)過程詳解

它們有一個(gè)負(fù)責(zé)監(jiān)聽的父進(jìn)程(Master),監(jiān)聽子進(jìn)程狀態(tài),發(fā)送 signal 給子進(jìn)程,接受來(lái)自終端的命令、信號(hào)等工作。父進(jìn)程可以說是整個(gè)系統(tǒng)啟動(dòng)後的入口。

啟動(dòng)命令解析

既然以命令模式(cli)運(yùn)行(注意與fpm 的區(qū)別,後者處理來(lái)自網(wǎng)頁(yè)端的請(qǐng)求) ,就必然有一個(gè)啟動(dòng)腳本解析命令,譬如說3.x版本(之前預(yù)設(shè)為daemon)新增一個(gè)-d 參數(shù),以表示守護(hù)程序運(yùn)行,解析到該參數(shù)設(shè)置self::$daemon = true, 隨後fork子進(jìn)程以脫離目前進(jìn)程組,設(shè)定進(jìn)程組組長(zhǎng)等工作。

這裡有兩個(gè)非常重要的參數(shù)$argc 和$argc,前者表示參數(shù)個(gè)數(shù),後者為一個(gè)數(shù)組,保存有指令的所有參數(shù),例如:sudo php start.php start -d, $argv就是array( [0]=>start.php, [1]=>start, [2]=>-d ),而解析主要用到$argv。

啟動(dòng)主要執(zhí)行下列步驟:

1、包含自動(dòng)載入器Autoloader?,載入各Application 下啟動(dòng)檔案;

2、設(shè)定?_appInitPath 根目錄;

3、解析,初始化參數(shù),執(zhí)行對(duì)應(yīng)指令。

下面是具體實(shí)作(workerman/worker.php):

public static function parseCommand()
    {
        // 檢查運(yùn)行命令的參數(shù)
        global $argv;
        $start_file = $argv[0]; 

        // 命令
        $command = trim($argv[1]);
        
        // 子命令,目前只支持-d
        $command2 = isset($argv[2]) ? $argv[2] : '';
        
        // 檢查主進(jìn)程是否在運(yùn)行
        $master_pid = @file_get_contents(self::$pidFile);
        $master_is_alive = $master_pid && @posix_kill($master_pid, 0);
        if($master_is_alive)
        {
            if($command === 'start')
            {
                self::log("Workerman[$start_file] is running");
            }
        }
        elseif($command !== 'start' && $command !== 'restart')
        {
            self::log("Workerman[$start_file] not run");
        }
        
        // 根據(jù)命令做相應(yīng)處理
        switch($command)
        {
            // 啟動(dòng) workerman
            case 'start':
                if($command2 === '-d')
                {
                    Worker::$daemonize = true;
                }
                break;
            // 顯示 workerman 運(yùn)行狀態(tài)
            case 'status':
                exit(0);
            // 重啟 workerman
            case 'restart':
            // 停止 workeran
            case 'stop':
                // 想主進(jìn)程發(fā)送SIGINT信號(hào),主進(jìn)程會(huì)向所有子進(jìn)程發(fā)送SIGINT信號(hào)
                $master_pid && posix_kill($master_pid, SIGINT);
                // 如果 $timeout 秒后主進(jìn)程沒有退出則展示失敗界面
                $timeout = 5;
                $start_time = time();
                while(1)
                {
                    // 檢查主進(jìn)程是否存活
                    $master_is_alive = $master_pid && posix_kill($master_pid, 0);
                    if($master_is_alive)
                    {
                        // 檢查是否超過$timeout時(shí)間
                        if(time() - $start_time >= $timeout)
                        {
                            self::log("Workerman[$start_file] stop fail");
                            exit;
                        }
                        usleep(10000);
                        continue;
                    }
                    self::log("Workerman[$start_file] stop success");
                    // 是restart命令
                    if($command === 'stop')
                    {
                        exit(0);
                    }
                    // -d 說明是以守護(hù)進(jìn)程的方式啟動(dòng)
                    if($command2 === '-d')
                    {
                        Worker::$daemonize = true;
                    }
                    break;
                }
                break;
            // 平滑重啟 workerman
            case 'reload':
                exit;
        }
    }

walker程式碼註解已經(jīng)非常詳盡,下面有幾點(diǎn)細(xì)節(jié):

1、檢查主進(jìn)程是否存活:17行的邏輯與操作,如果主進(jìn)程PID存在情況下,向該進(jìn)程發(fā)送信號(hào)0,實(shí)際上並沒有發(fā)送任何訊息,只是檢測(cè)該進(jìn)程(或進(jìn)程組)是否存活,同時(shí)也檢測(cè)當(dāng)前用戶是否有權(quán)限發(fā)送系統(tǒng)訊號(hào);

2、為什麼主程序PID會(huì)保存?系統(tǒng)啟動(dòng)後脫離目前terminal運(yùn)行,如果要執(zhí)行關(guān)閉或其他指令,此時(shí)是以另外的一個(gè)程序執(zhí)行該指令,如果我們連進(jìn)程PID都不知道,那該向誰(shuí)發(fā)訊號(hào)呢?

所以主進(jìn)程PID必須保存起來(lái),而且主進(jìn)程負(fù)責(zé)監(jiān)聽其他子進(jìn)程,所以它是我們繼續(xù)操作的入口。

Worker::runAll()

#php的socket程式設(shè)計(jì)其實(shí)和C差不多,後者對(duì)socket進(jìn)行了再包裹,並提供介面給php,在php下網(wǎng)路程式設(shè)計(jì)步驟大幅減少。

譬如:stream_socket_server?和?stream_socket_client?直接建立了server/client socke(php有兩套socket運(yùn)算子)。 wm則大量使用了前者,啟動(dòng)過程如下(註釋已經(jīng)非常詳盡):

public static function runAll()
    {
        // 初始化環(huán)境變量
        self::init();
        // 解析命令
        self::parseCommand();
        // 嘗試以守護(hù)進(jìn)程模式運(yùn)行
        self::daemonize();
        // 初始化所有worker實(shí)例,主要是監(jiān)聽端口
        self::initWorkers();
        //  初始化所有信號(hào)處理函數(shù)
        self::installSignal();
        // 保存主進(jìn)程pid
        self::saveMasterPid();
        // 創(chuàng)建子進(jìn)程(worker進(jìn)程)并運(yùn)行
        self::forkWorkers();
        // 展示啟動(dòng)界面
        self::displayUI();
        // 嘗試重定向標(biāo)準(zhǔn)輸入輸出
        self::resetStd();
        // 監(jiān)控所有子進(jìn)程(worker進(jìn)程)
        self::monitorWorkers();
    }

下面還是只說該過程的關(guān)鍵點(diǎn):

1、始化環(huán)境變量,例如設(shè)定主行程名稱、日誌路徑,初始化計(jì)時(shí)器等等;

2、解析命令列參數(shù),主要用到$argc 和$argc 用法同C語(yǔ)言;

3、產(chǎn)生守護(hù)進(jìn)程,以脫離當(dāng)前終端(兩年前大部分認(rèn)為PHP無(wú)法做daemon,其實(shí)這是個(gè)誤區(qū)!其實(shí)PHP在linux的進(jìn)程模型很穩(wěn)定,現(xiàn)在wm在商業(yè)的應(yīng)用已經(jīng)非常成熟,國(guó)內(nèi)某公司每天處理幾億的連接,用於訂單、支付調(diào)用,大家可以打消顧慮了);

4、初始化所有worker實(shí)例(注意,這裡是在主進(jìn)程做的,只是生成了一堆server 並沒有設(shè)定監(jiān)聽,多進(jìn)程模型是子程序做的監(jiān)聽,即IO復(fù)用);

5、為主程序註冊(cè)訊號(hào)處理函數(shù);

6、保存主進(jìn)程PID,當(dāng)系統(tǒng)運(yùn)行後,我們?cè)诮K端查看系統(tǒng)狀態(tài)或執(zhí)行關(guān)閉、重啟命令,是透過主進(jìn)程進(jìn)行通信,所以需要知道主進(jìn)程PID,我們知道在終端下敲入一個(gè)可執(zhí)行指令,實(shí)則是在目前終端機(jī)下新建一個(gè)子程序來(lái)執(zhí)行,所以我們需要得知主程序PID,以向WM主程序發(fā)送SIGNAL,這時(shí)訊號(hào)處理函數(shù)會(huì)擷取該訊號(hào),並透過回呼方式執(zhí)行。

7、建立子進(jìn)程,設(shè)定目前進(jìn)程使用者(root)。在多進(jìn)程模型中,兩類子進(jìn)程,分別監(jiān)聽不同的server位址,我們?cè)谥鬟M(jìn)程只是建立server並沒有設(shè)定監(jiān)聽,也沒有產(chǎn)生指定數(shù)目的server。

原因在於,我們?cè)谝粋€(gè)進(jìn)程多次創(chuàng)建同一個(gè)socket,會(huì)報(bào)錯(cuò), worker數(shù)目其實(shí)就是socket 數(shù)量,也就是該socket 的子進(jìn)程數(shù)目,子進(jìn)程繼承了父進(jìn)程上下文,但是只監(jiān)聽特定的socket 事件;

8、在子進(jìn)程中,將server socket 註冊(cè)監(jiān)聽事件,用到一個(gè)擴(kuò)展Event,可以實(shí)現(xiàn)IO復(fù)用,並註冊(cè)資料讀取回調(diào),同時(shí)也可註冊(cè)socket連接事件回調(diào);

9、輸入輸出重定向;

10、主程序監(jiān)聽子程序狀態(tài),在一個(gè)無(wú)限迴圈中呼叫pcntl_signal_dispatch() 函數(shù),用於擷取子程序退出狀態(tài),函數(shù)會(huì)一直阻塞,直到有子程序退出時(shí)才觸發(fā);

更多workerman相關(guān)知識(shí)請(qǐng)關(guān)注workerman教學(xué)欄位。

以上是workerman源碼分析之啟動(dòng)過程詳解的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
實(shí)作Workerman文件中的文件上傳與下載 實(shí)作Workerman文件中的文件上傳與下載 Nov 08, 2023 pm 06:02 PM

實(shí)現(xiàn)Workerman文件中的文件上傳與下載,需要具體程式碼範(fàn)例引言:Workerman是一款高效能的PHP非同步網(wǎng)路通訊框架,具備簡(jiǎn)潔、高效、易用等特點(diǎn)。在實(shí)際開發(fā)中,文件上傳和下載是常見的功能需求,本文將介紹如何使用Workerman框架實(shí)現(xiàn)文件的上傳和下載,並給出具體的程式碼範(fàn)例。一、檔案上傳:檔案上傳是指將本機(jī)上的檔案?jìng)鬏斨了欧鞫说牟僮?。下面是使?/p>

swoole和workerman哪個(gè)好 swoole和workerman哪個(gè)好 Apr 09, 2024 pm 07:00 PM

Swoole 和 Workerman 都是高效能 PHP 伺服器框架。 Swoole 以其非同步處理、出色的效能和可擴(kuò)展性而聞名,適用於需要處理大量並發(fā)請(qǐng)求和高吞吐量的專案。 Workerman 提供了非同步和同步模式的靈活性,具有直覺的 API,更適合易用性和處理較低並發(fā)量的專案。

如何實(shí)作Workerman文件的基本使用方法 如何實(shí)作Workerman文件的基本使用方法 Nov 08, 2023 am 11:46 AM

如何實(shí)現(xiàn)Workerman文件的基本使用方法簡(jiǎn)介:Workerman是一個(gè)高效能的PHP開發(fā)框架,它可以幫助開發(fā)者輕鬆建立高並發(fā)的網(wǎng)路應(yīng)用程式。本文將介紹Workerman的基本使用方法,包括安裝和設(shè)定、建立服務(wù)和監(jiān)聽連接埠、處理客戶端請(qǐng)求等。並給出相應(yīng)的程式碼範(fàn)例。一、安裝並設(shè)定Workerman在命令列中輸入以下命令來(lái)安裝Workerman:c

如何實(shí)作Workerman文件中的定時(shí)器功能 如何實(shí)作Workerman文件中的定時(shí)器功能 Nov 08, 2023 pm 05:06 PM

如何實(shí)現(xiàn)Workerman文件中的定時(shí)器功能Workerman是一款強(qiáng)大的PHP非同步網(wǎng)路通訊框架,它提供了豐富的功能,其中就包括定時(shí)器功能。使用定時(shí)器可以在指定的時(shí)間間隔內(nèi)執(zhí)行程式碼,非常適合定時(shí)任務(wù)、輪詢等應(yīng)用程式場(chǎng)景。接下來(lái),我將詳細(xì)介紹如何在Workerman中實(shí)現(xiàn)定時(shí)器功能,並提供具體的程式碼範(fàn)例。第一步:安裝Workerman首先,我們需要安裝Worker

如何實(shí)現(xiàn)Workerman文件中的反向代理功能 如何實(shí)現(xiàn)Workerman文件中的反向代理功能 Nov 08, 2023 pm 03:46 PM

如何實(shí)現(xiàn)Workerman文件中的反向代理功能,需要具體程式碼範(fàn)例簡(jiǎn)介:Workerman是一款高效能的PHP多進(jìn)程網(wǎng)路通訊框架,提供了豐富的功能和強(qiáng)大的效能,廣泛應(yīng)用於Web即時(shí)通訊、長(zhǎng)連接服務(wù)等場(chǎng)景。其中,Workerman也支援反向代理功能,可實(shí)現(xiàn)伺服器對(duì)外提供服務(wù)時(shí)的負(fù)載平衡和靜態(tài)資源快取等功能。本篇文章將介紹如何使用Workerman實(shí)現(xiàn)反向代理功

Workerman開發(fā):如何實(shí)現(xiàn)基於UDP協(xié)定的即時(shí)視訊通話 Workerman開發(fā):如何實(shí)現(xiàn)基於UDP協(xié)定的即時(shí)視訊通話 Nov 08, 2023 am 08:03 AM

Workerman開發(fā):基於UDP協(xié)議的即時(shí)視訊通話摘要:本文將介紹如何使用Workerman框架實(shí)現(xiàn)基於UDP協(xié)議的即時(shí)視訊通話功能。我們將深入了解UDP協(xié)議的特點(diǎn),並透過程式碼範(fàn)例展示如何建立一個(gè)簡(jiǎn)單但完整的即時(shí)視訊通話應(yīng)用程式。引言:在網(wǎng)路通訊中,即時(shí)視訊通話是一項(xiàng)非常重要的功能。傳統(tǒng)的TCP協(xié)定在實(shí)現(xiàn)即時(shí)性較高的視訊通話時(shí),可能會(huì)有傳輸延遲等問題。而UDP

如何使用Workerman建構(gòu)高可用性負(fù)載平衡系統(tǒng) 如何使用Workerman建構(gòu)高可用性負(fù)載平衡系統(tǒng) Nov 07, 2023 pm 01:16 PM

如何使用Workerman建立高可用性負(fù)載平衡系統(tǒng),需要具體程式碼範(fàn)例在現(xiàn)代技術(shù)領(lǐng)域中,隨著網(wǎng)路的快速發(fā)展,越來(lái)越多的網(wǎng)站和應(yīng)用程式需要處理大量的並發(fā)請(qǐng)求。為了實(shí)現(xiàn)高可用性和高效能,負(fù)載平衡系統(tǒng)成為了必不可少的組件之一。本文將介紹如何使用PHP開源框架Workerman建構(gòu)一個(gè)高可用性的負(fù)載平衡系統(tǒng),並提供具體的程式碼範(fàn)例。一、Workerman簡(jiǎn)介Worke

實(shí)現(xiàn)Workerman文件中的文件傳輸功能 實(shí)現(xiàn)Workerman文件中的文件傳輸功能 Nov 08, 2023 pm 03:39 PM

Workerman是基於PHP開發(fā)的高效能非同步事件驅(qū)動(dòng)框架,它可以輕鬆實(shí)現(xiàn)TCP/UDP協(xié)定下的長(zhǎng)連線開發(fā)。除此之外,Workerman也提供了實(shí)現(xiàn)檔案?jìng)鬏數(shù)墓δ?,可以用於大檔案?jìng)鬏?、資料備份等場(chǎng)景。本文將介紹如何在Workerman中實(shí)現(xiàn)檔案?jìng)鬏敼δ?,並提供具體的程式碼範(fàn)例。一、文件上傳功能實(shí)現(xiàn)文件上傳功能需要客戶端將要上傳的文件傳送給服務(wù)端,服務(wù)端驗(yàn)證

See all articles