最近在研究Swoole
,原來一直聽別人在說Swoole
能夠加速,一直都是懵逼的。在研究了Swoole
以後,我有了一些本身的理解。php
對於 PHP
處理網絡請求,你們基本上也都是再用 CGI
的方式來作的。那麼,什麼是 CGI
呢。程序員
CGI
,全稱 Common Gateway Interface
,中文稱做「公共網關接口」。也許有不少人認爲 CGI
是一個程序,沒錯,曾經的我也是這麼認爲的。直到我從《圖解HTTP》開始細細地研究HTTP
協議以後,我才知道,原來 CGI
是一種協議。任何編程語言,均可以實現 CGI
,因此任何語言均可以做爲網站的後臺語言(扯遠了)。編程
上面說了,CGI
是一個協議,因此,PHP
有本身對 CGI
的實現,那就是 PHP-CGI
。但是呢,隨着技術的發展,人們開始意識到,PHP-CGI
的性能不是那麼盡如人意。咱們知道,PHP
在運行的時候,是依賴配置文件 php.ini
的。因此,每當 PHP-CGI
開始工做的時候,它是完徹底全的一個新進程,它須要從新加載配置文件並初始化,這就形成了很大的資源和時間的浪費。bootstrap
那麼,怎麼才能避免這種浪費呢,聰明的程序員們想出了另一種方法:咱們爲何不預先加載好配置,而後,每個執行的任務只須要複製當前的進程,不就能避免上面的浪費了麼。因而, FastCGI
便橫空出世。網絡
FastCGI
,全稱 Fast Common Gateway Interface
,中文譯做「快速公共網管接口」。沒錯,這又是個協議。固然,這個協議並非由於 PHP
纔有的。app
幾乎全部的 Web
容器都實現了 FastCGI
的功能。首先是 httpd
。對於 PHP
來講,httpd
是經過自身來實現一個 FastCGI
的模塊的。它會預先加載好 php.ini
文件中的配置。待到有請求進入須要 PHP
處理時,PHP
就不須要再對 php.ini
從新加載了。這也就是每改動過 php.ini
後都要重啓 httpd
服務的緣由。框架
php-fpm
也是 FastCGI
的一種實現。一般咱們是將 Nginx
的 PHP
處理部分代理到 php-fpm
的端口上,交給 php-fpm
來處理。而 php-fpm
一樣是經過預先加載配置,而後給到子進程的方式的,它會對進程作一些管理。編程語言
辣麼問題來了,php-fpm
雖然實現了 FastCGI
,可是,它在處理請求的時候,依然要從新運行一個腳本,像 Laravel
同樣的框架,一開始就要加載辣麼多依賴和文件,依然是一個不小的開銷。咱們看一下 Laravel
的 public/index.php
的源碼。php-fpm
require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);
看看前面兩條語句,這須要加載多少個依賴啊,這都是大把大把的時間和資源啊,每一次請求都須要加載一邊,真是心疼啊。性能
那麼,咱們爲何不能像以前同樣,可以不從新加載配置文件的 FastCGI
,來一個不用加載這麼多的依賴的方式呢?
固然能夠啦,這時候 Swoole
就派上用場了。既然是經過 $app->make
的方式來生成一個新的 Kernel
對象,那麼 Application
的對象 $app
天然是不會有什麼改變的了。因此,咱們能夠在收到請求以前,就把 $app
給生成好,這樣就會快了,不是麼?咱們能夠對它進行一個簡單的改造。
require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; $serv = new \Swoole\Server\Http('127.0.0.1', 9501); $serv->on('request', function ($req, $res) use ($app) { $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $res->end($response); $kernel->terminate($request, $response); }); $serv->start();
好了,咱們如今就能夠經過執行這個腳原本監聽9501端口了。而後就像 Nginx
配置 php-fpm
同樣來配置它就能夠了。這樣咱們能夠看到,在收到請求以前,就已經把依賴加載乾淨了,剩下的就是處理請求了。
固然個人這個改動很簡陋,根本沒法用於生產環境的,只是提供一個例子。
以上只是我本身的理解和對我本身的理解進行的總結。對於 Swoole
我還在探索當中,由於它須要的只是實在是太多了,須要一點一點積累。本文可能有不對的地方,歡迎各位大神來拍磚!