国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Swoft 源碼剖析 - Swoole和Swoft的那些事 (Http/Rpc服務(wù)篇)

張漢慶 / 2159人閱讀

摘要:和服務(wù)關(guān)系最密切的進(jìn)程是中的進(jìn)程組,絕大部分業(yè)務(wù)處理都在該進(jìn)程中進(jìn)行。隨后觸發(fā)一個(gè)事件各組件通過(guò)該事件進(jìn)行配置文件加載路由注冊(cè)。事件每個(gè)請(qǐng)求到來(lái)時(shí)僅僅會(huì)觸發(fā)事件。服務(wù)器生命周期和服務(wù)基本一致,詳情參考源碼剖析功能實(shí)現(xiàn)

作者:bromine
鏈接:https://www.jianshu.com/p/4c0...
來(lái)源:簡(jiǎn)書
著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。
Swoft Github: https://github.com/swoft-clou...

Swoft源碼剖析系列目錄:https://segmentfault.com/a/11...
前言

SwoftPHPer圈中是一個(gè)門檻較高的Web框架,不僅僅由于框架本身帶來(lái)了很多新概念和前沿的設(shè)計(jì),還在于Swoft是一個(gè)基于Swoole的框架。SwoolePHPer圈內(nèi)學(xué)習(xí)成本最高的工具沒(méi)有之一,雖然Swoft的出現(xiàn)降低了Swoole的使用成本,但如果你對(duì)Swoole本身了解不夠深入,仍然很難避免栽進(jìn)種種"坑"中。

考慮到這個(gè)現(xiàn)狀,也為降低閱讀難度,后續(xù)幾個(gè)和Swoole聯(lián)系較為密切的機(jī)制,筆者會(huì)調(diào)整寫作思路,將文章的定位從 「幫助讀者深入理解Swoft」 調(diào)整為 「幫助讀者理解Swoft和Swoole」,敘述節(jié)奏也會(huì)放慢。

三種PHP應(yīng)用的Web模型

LNMPLAMP是絕大多數(shù)PHPer最熟悉的基礎(chǔ)Web架構(gòu),這里以常見(jiàn)的LNMP作為例子描述一個(gè)常見(jiàn) 無(wú)Swoole應(yīng)用的構(gòu)件組成:Nginx充當(dāng)Web Service, PHP-FPM維護(hù)一個(gè)進(jìn)程池去運(yùn)行Web項(xiàng)目。

對(duì)比更古老的CGI模型,PHP-FPM已經(jīng)引入了進(jìn)程常駐的概念,避免每次請(qǐng)求創(chuàng)建并銷毀進(jìn)程的開銷以及拓展加載的開銷,但是每個(gè)請(qǐng)求仍然要執(zhí)行PHP RINITRSHUTDOWN 之間的所有流程,包括重新加載一次框架源碼以及項(xiàng)目代碼,造成極大的性能浪費(fèi)。

這種模型的優(yōu)點(diǎn)是簡(jiǎn)單成熟和穩(wěn)定,一次運(yùn)行隨后銷毀 帶來(lái)的開發(fā)便捷性是PHP能夠流行起來(lái)的原因之一。市面上絕大多數(shù)PHP項(xiàng)目使用的都是基于該種架構(gòu)的變體。

LNMP-with-SwooleLNMP的一種變體,其在LNMP的基礎(chǔ)上引入了Swoole組件。
PHP-FPM一樣,Swoole有一套自己的進(jìn)程管理機(jī)制。但由于代碼變得高度常駐和編程思維需要從同步到異步的轉(zhuǎn)變,所以Swoole和傳統(tǒng)的基于PHP-FPMWeb框架親和度很低,即使是適配升級(jí)過(guò)的老式Web框架,目前在Swoole上運(yùn)行的表現(xiàn)往往并不好。

因此出現(xiàn)了這在這種折中方案,并沒(méi)有直接將原有PHP代碼運(yùn)行在Swoole中,而是使用Swoole搭建了一個(gè)服務(wù),系統(tǒng)通過(guò)接口與Swoole通信,從而為Web項(xiàng)目補(bǔ)充了異步處理的能力。我稱呼這種同時(shí)使用PHP-FPMSwoole的系統(tǒng)為 半Swoole應(yīng)用。因?yàn)榻尤牒?jiǎn)單,所以是絕大多數(shù)現(xiàn)有項(xiàng)目?jī)?yōu)先考慮的Swoole接入方案。

LNMP-with-Swoole模型雖然引入了Swoole和異步處理能力,但是核心還是PHP-FPM,實(shí)際上還遠(yuǎn)遠(yuǎn)沒(méi)有發(fā)揮出Swoole的真正優(yōu)勢(shì)。

Swoole-HTTP-ServerLNMP-with-Swoole相比有巨大的變化,這種模型中充當(dāng)Web Server角色的構(gòu)件不僅僅有Nginx,應(yīng)用本身也包含了一個(gè)內(nèi)建Web Server,不過(guò)由于Swoole Http Server不是專業(yè)的HTTP Server,對(duì)Http的處理不完善 ,因此仍然需要使用Nginx作為靜態(tài)資源服務(wù)器以及反代,Swoole HTTP Server僅僅處理PHP相關(guān)的HTTP流量。

一方面由于Swoole已經(jīng)包含了WebServer,不再需要實(shí)現(xiàn)CGI或者Fast-CGI的通用協(xié)議去和Web Server通信,另一方面Swoole有自己的進(jìn)程管理,因此PHP-FPM可以直接被去除了。對(duì)于PHP資源而言,在這種模型中,Swoole Http Server的地位相當(dāng)于傳統(tǒng)模型中的NginxPHP-FPM之和。

一次加載常駐內(nèi)存,不同的請(qǐng)求間基本上復(fù)用了onRequest以外的所有流程,使得每個(gè)請(qǐng)求的開銷大大降低;異步IO的特性使得這種模型吞吐量遠(yuǎn)遠(yuǎn)高于傳統(tǒng)的LNMP模型。另外相對(duì)于獨(dú)立的Swoole服務(wù),內(nèi)嵌在Web系統(tǒng)中的Swoole使用更加的直接方便,支持更好。

Swoft 和 Swoole 的關(guān)系是什么 ?

Swoole是一個(gè)異步引擎,核心是為PHP提供異步IO執(zhí)行的能力,同時(shí)提供一套異步編程可能會(huì)用到的工具集。

Swoole-HTTP-ServerSwoole的一個(gè)組件,是SwooleServer中的一種,提供了一個(gè)適合Swoole直接運(yùn)行的HttpServer環(huán)境。

Swoft一個(gè)現(xiàn)代的Web框架Swoole親和性高,同時(shí)也是上面提到的Swoole-HTTP-Server模型的一個(gè)實(shí)踐。

Swoft管理著該Web模型中的Swoole,以及Swoole-HTTP-Server對(duì)開發(fā)者屏蔽Swoole的種種復(fù)雜操作細(xì)節(jié),并作為一個(gè)Web框架向開發(fā)者提供各種Web開發(fā)需要用到的路由MVC數(shù)據(jù)庫(kù)訪問(wèn)等功能組件等。

Swoft 是如何使用 Swoole 的 ?

最核心的就是HttpServer以及RpcServer

HTTP 服務(wù)器

Swoft直接使用的是Swoole內(nèi)建的SwooleHttpServer,它已經(jīng)處理好所有HTTP層面的所有東西,我們只需要關(guān)注應(yīng)用本身,我們來(lái)看一下HTTP服務(wù)幾個(gè)重要生命周期點(diǎn)。

Swoole 啟動(dòng)前

這個(gè)階段進(jìn)行的行為有幾個(gè)特征

基礎(chǔ)bootstrap行為:如必須的常量定義,Composer加載器引入,配置讀取等;

需要生成被所有Worker/Task進(jìn)程共享的程序全局期的對(duì)象,如SwooleLock,SwoftMemoryTable的創(chuàng)建;

啟動(dòng)時(shí),所有進(jìn)程中合計(jì)只能執(zhí)行一次的操作:如前置Process的啟動(dòng);

Bean容器基本初始化,以及項(xiàng)目啟動(dòng)流程需要的coreBean的加載。

這塊涉及東西比較雜,為控制篇幅后續(xù)用多帶帶文章介紹。

Http服務(wù)關(guān)系最密切的進(jìn)程是Swoole中的Worker進(jìn)程(組),絕大部分業(yè)務(wù)處理都在該進(jìn)程中進(jìn)行。
對(duì)于每個(gè)Swoole事件Swoft都提供了對(duì)應(yīng)的Swoole監(jiān)聽器(對(duì)應(yīng)@SwooleListener注解)作為事件機(jī)制的封裝。要理解SwoftHttpServer是如何在Swoole下運(yùn)行的我們重點(diǎn)需要關(guān)注下兩個(gè)在兩個(gè)Swoole事件swoole.workerStartswoole.onRequest

swoole.workerStart 事件

WorkerStart事件在TaskWorker/Worker進(jìn)程啟動(dòng)時(shí)發(fā)生,每個(gè)TaskWorker/Worker進(jìn)程里都會(huì)執(zhí)行一次。
這是個(gè)關(guān)鍵節(jié)點(diǎn),因?yàn)?b>swoole.workerStart回調(diào)之后新建的對(duì)象都是進(jìn)程全局期的,使用的內(nèi)存都屬于特定的Task/Worker進(jìn)程,相互獨(dú)立。也只有在這個(gè)階段或以后初始化的部分才是可以被熱重載的。
事件底層關(guān)鍵代碼如下:

// SwoftBootstrapServerServerTrait.php
/**
 * @param bool $isWorker
 * @throws InvalidArgumentException
 * @throws ReflectionException
 */
protected function reloadBean(bool $isWorker)
{
    BeanFactory::reload();
    $initApplicationContext = new InitApplicationContext();
    $initApplicationContext->init();

    if($isWorker && $this->workerLock->trylock() && env("AUTO_REGISTER", false)){
        App::trigger(AppEvent::WORKER_START);
    }
}

這里做的事情有3點(diǎn)

初始化Bean容器:
上文中的BeanFactory::reload();就是SwoftBean容器初始化入口,注解的掃描也是在此處進(jìn)行(實(shí)際上這個(gè)說(shuō)法并不準(zhǔn)確,Bean容器真正的初始化階段在Swoole Server啟動(dòng)前的BootStrap階段就已經(jīng)進(jìn)行了,只不過(guò)那時(shí)進(jìn)行的是少部分初始化,相對(duì)swoole.workerStart中的初始化的Bean數(shù)量,比重很小)。在workerStart中初始化Bean容器是Swoft可以熱更新代碼的基礎(chǔ)。

初始化的應(yīng)用上下文
initApplicationContext->init()會(huì)注冊(cè)Swoft事件監(jiān)聽器(對(duì)應(yīng)@Listener),方便用戶處理Swoft應(yīng)用本身的各種鉤子。隨后觸發(fā)一個(gè)swoft.applicationLoader事件,各組件通過(guò)該事件進(jìn)行配置文件加載,HTTP/RPC路由注冊(cè)。

服務(wù)注冊(cè)
具體內(nèi)容會(huì)在服務(wù)治理章節(jié)講述。

swoole.onRequest 事件

每個(gè)HTTP請(qǐng)求到來(lái)時(shí)僅僅會(huì)觸發(fā)swoole.onRequest事件。
框架代碼本身都是由大量進(jìn)程全局期和少量程序全局期的對(duì)象構(gòu)成,而onReceive中創(chuàng)建的對(duì)象譬如$request$response都是請(qǐng)求期的,隨著HTTP請(qǐng)求的結(jié)束而回收。

事件底層關(guān)鍵代碼如下:

/**
 * @param array ...$params
 * @return PsrHttpMessageResponseInterface
 * @throws InvalidArgumentException
 */
public function dispatch(...$params): ResponseInterface
{
    /**
     * @var RequestInterface $request
     * @var ResponseInterface $response
     */
    list($request, $response) = $params;

    try {
        // before dispatcher
        $this->beforeDispatch($request, $response);

        // request middlewares
        $middlewares = $this->requestMiddleware();
        $request = RequestContext::getRequest();
        $requestHandler = new RequestHandler($middlewares, $this->handlerAdapter);
        $response = $requestHandler->handle($request);

    } catch (Throwable $throwable) {
        /* @var ErrorHandler $errorHandler */
        $errorHandler = App::getBean(ErrorHandler::class);
        $response = $errorHandler->handle($throwable);
    }

    $this->afterDispatch($response);

    return $response;
}

beforeDispatch($request, $response):
設(shè)置請(qǐng)求上下文,并觸發(fā)一個(gè)swoft.beforeRequest事件。

RequestHandler->handle($request):
執(zhí)行各個(gè) 中間件 和請(qǐng)求對(duì)應(yīng)的 Action,具體處理可以參考RPC章節(jié),原理基本相同。

$afterDispatch($response):
整理HTTP響應(yīng)報(bào)文發(fā)送客戶端并觸發(fā)swoft.resourceRelease(詳情在連接池一文中提及)事件和swoft.afterRequest事件

總的來(lái)說(shuō),縱觀這幾個(gè)生命周期點(diǎn)你需要搞清楚幾件事:

SwooleWorker進(jìn)程是你絕大多數(shù)HTTP服務(wù)代碼的運(yùn)行環(huán)境。

一部分初始化和加載操作在SwooleServer啟動(dòng)前完成,一部分在swoole.workerStart事件回調(diào)中完成,前者無(wú)法熱重載但可能被多個(gè)進(jìn)程共享。

初始化代碼只會(huì)在系統(tǒng)啟動(dòng)和Worker/Task進(jìn)程啟動(dòng)時(shí)執(zhí)行一次, 不像PHP-FPM每次請(qǐng)求都會(huì)執(zhí)行一次,框架對(duì)象也不像PHP-FPM會(huì)隨請(qǐng)求返回而銷毀。

每次請(qǐng)求都會(huì)觸發(fā)一次swoole.onRequest事件,里面就是我們的請(qǐng)求處理代碼真正運(yùn)行的地方,只有這事件內(nèi)產(chǎn)生的對(duì)象才會(huì)在請(qǐng)求結(jié)束時(shí)被回收。

RPC服務(wù)器

生命周期和HTTP服務(wù)基本一致,詳情參考《Swoft源碼剖析-RPC功能實(shí)現(xiàn)》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/29027.html

相關(guān)文章

  • Swoft 源碼剖析 - 目錄

    摘要:作者鏈接來(lái)源簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。同時(shí)順手整理個(gè)人對(duì)源碼的相關(guān)理解,希望能夠稍微填補(bǔ)學(xué)習(xí)領(lǐng)域的空白。系列文章只會(huì)節(jié)選關(guān)鍵代碼輔以思路講解,請(qǐng)自行配合源碼閱讀。 作者:bromine鏈接:https://www.jianshu.com/p/2f6...來(lái)源:簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。Swoft...

    qpwoeiru96 評(píng)論0 收藏0
  • Swoft 源碼剖析 - SwooleSwoft那些(Task投遞/定時(shí)任務(wù))

    摘要:作為定時(shí)任務(wù)的執(zhí)行者,通過(guò)每喚醒自身一次,然后把執(zhí)行表遍歷一次,挑選當(dāng)下需要執(zhí)行的任務(wù),通過(guò)投遞出去并更新該任務(wù)執(zhí)行表中的狀態(tài)。 作者:bromine鏈接:https://www.jianshu.com/p/b44...來(lái)源:簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。Swoft Github: https://github.com/swoft-clou.....

    vvpvvp 評(píng)論0 收藏0
  • Swoft 源碼剖析 - RPC 功能實(shí)現(xiàn)

    摘要:值得一提的是目前的服務(wù)即服務(wù),暫沒(méi)有其他的服務(wù)功能,所以基本上相關(guān)的配置指代的就是。會(huì)將請(qǐng)求傳遞給各個(gè)中間件,最終最終傳遞給處理。源碼剖析系列目錄 作者:bromine鏈接:https://www.jianshu.com/p/411...來(lái)源:簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。Swoft Github: https://github.com/swo...

    marser 評(píng)論0 收藏0
  • Swoft 源碼剖析 - 代碼自動(dòng)更新機(jī)制

    摘要:作者鏈接來(lái)源簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。文件重載管理進(jìn)程注冊(cè)了一個(gè)名為的該進(jìn)程會(huì)在系統(tǒng)引導(dǎo)的最后一個(gè)階段,即啟動(dòng)前啟動(dòng)。 作者:bromine鏈接:https://www.jianshu.com/p/e63...來(lái)源:簡(jiǎn)書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。Swoft Github: https://githu...

    iflove 評(píng)論0 收藏0
  • SwooleSwoft應(yīng)用

    摘要:在中的應(yīng)用官網(wǎng)源碼解讀號(hào)外號(hào)外歡迎大家我們開發(fā)組定了一個(gè)就線下聚一次的小目標(biāo)上一篇源碼解讀反響還不錯(cuò)不少同學(xué)推薦再加一篇講解一下中使用到的功能幫助大家開啟的實(shí)戰(zhàn)之旅服務(wù)器開發(fā)涉及到的相關(guān)技術(shù)領(lǐng)域的知識(shí)非常多不日積月累打好基礎(chǔ)是很難真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的應(yīng)用 swoft 官網(wǎng): https://www.sw...

    EscapedDog 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<