<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                [toc] >[info] 用于替代PHP-FPM同步阻塞的模式。實現異步非阻塞高性能的web服務 ## 優勢 * 性能的數十倍的提升; * 可以在`Apache`/`Nginx`等傳統WEB服務器和`Swoole`之間切換部署; * **在此模式下,還可以直接在控制器中調用`swoole/server`的方法,比如定時,任務異步投遞,協程等等** > 本例使用的是thinkphp5.1的擴展包, 本文只做實操記錄與源碼分析,詳細內容查看 [ThinkPHP 5.1 Swoole 快速上手指南](http://www.hmoore.net/thinkphp/think-swoole/722895)。 ~~~ composer require topthink/think-swoole # 啟動 php think swoole ~~~ ## 理解性能提升 原生的php-fpm是同步阻塞模式的,PHP-FPM 會創建一個主進程,控制何時以及如何將HTTP請求轉發給一個或多個子進程處理。PHP-FPM主進程還控制著什么時候創建(處理Web應用更多的流量)和銷毀(子進程運行時間太久或不再需要了)。 <br /> 而swoole-httpserver是異步非阻塞模式的。它常駐于內存,并基于事件回調。 **我們先通過ab壓測分別壓測不同模式下的同一PHP程序** `這里壓的是開了debug的thinkphp5.1默認頁面` ~~~ // -n 2000表示總請求數為2000 // -c 100 表示并發用戶數為100 // -k 使用HTTP的KeepAlive特性 ab -c 100 -n 2000 -k http://127.0.0.1:9501/ ~~~ 關于ab壓測工具的安裝與使用:[https://cloud.tencent.com/developer/article/1333772](https://cloud.tencent.com/developer/article/1333772) **在php-fpm模式下** ![](https://i.loli.net/2019/04/12/5cb055468f405.png) **在swoole-httpserver模式下** ![](https://i.loli.net/2019/04/12/5cb056319e8c7.png) >[info] 如圖所見,幾十倍近百倍的性能提升。**注意:**這可不是壓 `hello world` 哦,而是壓加載了93個文件的框架默認頁。 >[danger] 注意,異步或協程模式下的httpserver中不能有同步阻塞的代碼,否則就會變成同步,如果變成同步以后,性能還遠遠不如**PHP-fpm** > [PHP中哪些函數是同步阻塞的](https://wiki.swoole.com/wiki/page/474.html)。 **目前TP-swoole2.0版本對底層數據庫的協程是還不支持的!到3.0版本才支持** ### 異步的優勢 * 高并發,同步阻塞IO模型的并發能力依賴于進程/線程數量,例如`php-fpm`開啟了200個進程,理論上最大支持的并發能力為200。如果每個請求平均需要100ms,那么應用程序就可以提供2000qps。異步非阻塞的并發能力幾乎是無限的,可以發起或維持大量并發TCP連接 * 無IO等待,同步模型無法解決`IOWait`很高的場景,如上述例子每個請求平均要10s,那么應用程序就只能提供20qps了。而異步程序不存在IO等待,所以無論請求要花費多長時間,對整個程序的處理能力沒有任何影響 ### 同步的優勢 * 編碼簡單,同步模式編寫/調試程序更輕松 * 可控性好,同步模式的程序具有良好的過載保護機制,如在下面的情況異步程序就會出問題 * Accept保護,同步模式下一個TCP服務器最大能接受`進程數+Backlog`個TCP連接。一旦超過此數量,Server將無法再接受連接,客戶端會連接失敗。避免服務器Accept太多連接,導致請求堆積 ## 配置問題 如果應用目錄`application`因為使命名空間更具語義化而更改為`app`的話,要手動指定配置項`file_monitor_path` ~~~ 'file_monitor_path' => ['/home/wwwroot/XGservice/app/','/home/wwwroot/XGservice/config/'], // 文件監控目錄 默認監控application和config目錄 ~~~ >[warning] 切換成swoole模式后,應用就不是從入口文件index.php啟動了。而是在onWorkerStart回調中啟動,啟動的是think/swoole/application(繼承自think/app) ## 原生實現 [Http\\Server](https://wiki.swoole.com/wiki/page/327.html) ~~~ use Swoole\Http\Server; $http = new Server("0.0.0.0", 9501); $http->on('request', function ($request, $response) { $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start(); ~~~ `Http\Server`繼承自`Server`,是一個的`Http`服務器實現。`Http\Server`支持同步和異步2種模式。無論是同步模式還是異步模式,`Http\Server`都可以維持大量`TCP`客戶端連接。同步/異步僅僅體現在對請求的處理方式上。 >[info] `Http/WebSocket`服務器都是繼承自`Server`,所以`Server`提供的`API`,如`task/finish/tick`等都可以使用 ## 擴展源碼分析 `/vendor/topthink/think-swoole/src/command/Swoole.php` 1. 服務啟動前,有鉤子監聽后續可增加鉤子擴展業務 ~~~ $hook = Container::get('hook'); $hook->listen("swoole_server_start", $swoole); ~~~ 2. **在Worker進程啟動時也預留了鉤子,同時調用了config里面配置的閉包或者類文件(run方法)** ~~~ // vendor/topthink/think-swoole/src/Http.php:142 // 此步就是原生中on回調onWokerstart //onWokerstart預留的鉤子 $hook = Container::get('hook'); $hook->listen('swoole_worker_start', ['server' => $server, 'worker_id' => $worker_id]); // 閉包或者類文件 $wokerStart = Config::get('swoole.wokerstart'); ~~~ >[info] swoole是基于事件的。thinkphp-swoole在顯式的指定了onWorkerStart(server的回調事件),onRequest(httpServer的回調事件),其它事件可以在 3. 通過 [Process::kill](https://wiki.swoole.com/wiki/page/p-process.html) 實現 `stop`,`reload` 管理 ~~~ # 檢測進程是否存在,不會發送信號 Process::kill($pid, 0); # stop Process::kill($pid, SIGTERM); # reload 柔性重啟 Process::kill($pid, SIGUSR1); # start /* $swoole = new Swoole\Http\Server("0.0.0.0", 9501,SWOOLE_PROCESS, SWOOLE_SOCK_TCP); */ $swoole->option($this->config); $swoole->start(); # restart # 就是stop之后再start ~~~ 4. 響應事件 這段代碼寫得可以,值得借鑒 ``` // vendor/topthink/think-swoole/src/Server.php:93 protected $event = ['Start', 'Shutdown', 'WorkerStart', 'WorkerStop', 'WorkerExit', 'Connect', 'Receive', 'Packet', 'Close', 'BufferFull', 'BufferEmpty', 'Task', 'Finish', 'PipeMessage', 'WorkerError', 'ManagerStart', 'ManagerStop', 'Open', 'Message', 'HandShake', 'Request']; // 循環判斷,如果有當前回調方法就注冊 foreach ($this->event as $event) { if (method_exists($this, 'on' . $event)) { $this->swoole->on($event, [$this, 'on' . $event]); } } ``` ## `Cookie`和`Session` >[danger] 由于`Swoole`的特殊性,擴展本身接管了`Cookie`類和`Session`類的處理,因此不要調用(包括依賴注入)`think\Cookie`和`think\Session`類,而應該改為`think\swoole\Cookie`類和`think\swoole\Session`類。并且所有PHP內置的`session`函數都是無效的,`think-swoole`擴展單獨封裝了一個`Session`類,和系統的`Session`機制無關。 擴展雖然提供了基于`swoole_table`和`ThinkPHP`緩存的混合解決方案。但建議使用緩存機制來處理`Session`,如果你的應用比較大,則應該配置使用`redis`之類的緩存機制更加適合,直接在你的`cache.php`中定義相關緩存配置即可。 >[info] 其實在實際的項目開發中,更多的是開發api接口,而且都是基于JWT的身份驗證,cookie和session反而用得很少。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看