2020年7月24日 星期五

《面試官別再問》提高 Laravel 框架性能 PHP7 + Swoole + Stone

PHP每次的每次請求結束, 都會釋放掉執行中建立的所有資源。這樣有一個很大的好處:PHP程序員基本不用費力去考慮資源釋放的問題,諸如內存,IO句柄,數據庫連接等,請求結束時PHP將全部釋放。PHP程序員幾乎不用關心內存釋放的問題,也很難寫出內存泄露的程序。這讓PHP變得更加簡單容易上手, 直抒心意。但是也帶來了一個壞處:PHP很難在請求間復用資源, 類似PHP框架這種耗時的工作, 每次請求都需要反復做——即使每次都在做同樣的事情。也正因為如此,在PHP發展過程中,關於是否使用框架的爭論也從未停止過。

Stone主要優化的就是這個問題。 在框架資源初始化結束后再開啟一個FastCGI服務,這樣, 新的請求過來是直接從資源初始化結束后的狀態開始,避免每次請求去做資源初始化的事情。所以, 本質上, Stone運行時是常駐內存的,它和PHP-FPM一樣,是一個FastCGI的實現,不同的是, FPM每次執行請求都需要重新初始化框架, Stone直接使用初始化的結果。

同樣,事情總是有好有壞。壞處是:PHP編程變得更難了, 你需要考慮內存的釋放,需要關心PHP如何使用內存。甚至, 你需要了解使用的框架,以免『不小心』寫出讓人『驚喜』的效果。同時, PHP的調試變得更難, 因為每次修改程序后需要重啟進程才能看到效果。事實上開發Stone時針對這方面做了不少工作。好處是:程序的性能得到極大的提高。 當然, 客觀上的一些利好因素是: PHP的內存回收已經相當穩定和高效, Swoole穩定性已經在相當多的項目中得到驗證,Laravel代碼質量相當高。

按照Laravel官方文檔安裝laravel,如果已經安裝可以跳過

composer安裝stone內核

composer require stone/kernel:dev-master
編輯config / app.php,添加Provider

 'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    Illuminate\Auth\AuthServiceProvider::class,
    // 省略很多行

    /*
     * Package Service Providers...
     */
    Stone\StoneServiceProvider::class,

    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
],
編輯app / Console / Kernel.php,添加新命令

protected $commands = [
    \Stone\Console\Commands\StoneServer::class,
];
Stone的安裝已經完成,正常情況下stone:server的命令應該可以正常執行了

php ./artisan stone:server --help

Usage:
    stone:server [options]

Options:
      --debug
      --start
      --reload
      --stop
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  A FastCGI server bases on swoole and laravel
下面我們繼續,讓服務器運行起來,首先需要設置一些服務器的參數,我們需要新建一個config / stone.php

<?php
return [
    'server' => [
        'user' => 'www-data', //運行用戶,一般和php-fpm運行用戶相同
        'group' => 'www-data', //運行組,同上
        'domain' => '/var/run/stone-server-fpm.sock', // Unix域套接字地址,使用與nginx進程通信,推薦保持可用,如果系統不支持也可以是ip地址
        'port' => 9101, // 端口
        'handler' => 'App\Servers\Handler', //請求處理器,一個類名
        'pid' => '/var/run/stone.pid', //進程文件
    ]
];
建立Handler,新建app / Servers / Handler.php

<?php namespace App\Servers;

use Stone\Contracts\RequestHandler;
use Response;

class Handler implements RequestHandler
{
    public function process()
    {
        return Response::make('hello, stone server!');
    }

    public function onWorkerStart()
    {   
    }

    public function handleException($e)
    {   
    }
}
啟動服務器,正常情況下會顯示一個ok

php artisan swoole:http stop
php artisan swoole:http start

sudo php artisan stone:server --stop
sudo php artisan stone:server --start

沒有留言:

張貼留言