2021年3月3日 星期三

測試 - 使用 Swoole 加速 Laravel

Swoole 這名稱聽過好一陣子了,但聽起來感覺不怎麼特別,另外也沒有特別要求速度的網頁,或者使用的 OS 是老掉牙的 Windows Server 2003,就沒什麼很注意。最近稍有空閒,想找點新東西來玩玩,活絡一下大腦,才稍微深入研究探討。

首先看一下執行的畫面,嗯,網頁主要是有個圖比較好看。


設定測試環境

現代程式開發人員的好處就是,不用在自己日常用的電腦上裝一堆不知有沒有的軟體來測試新的東西,只要寫個 docker 的設定檔,就可以弄一個測試環境。測試 Swoole 的 Dockerfile 如下。

FROM centos:7.9.2009

RUN yum -y install \
      http://rpms.famillecollet.com/enterprise/remi-release-7.rpm \
   && yum -y install --enablerepo=remi,remi-php70 \
        httpd php php-pdo php-mysqlnd \
        php-xml php-mbstring php-mcrypt \
        php-opcache php-pecl-swoole2 unzip \
    && yum clean all \
    && rm -rf /var/cache/yum \
    && curl -o /usr/bin/composer \
       https://getcomposer.org/download/1.10.20/composer.phar \
    && chmod a+x /usr/bin/composer

#port and entry
EXPOSE 80

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

其中,大部分是 Laravel 使用的功能,只有 php-pecl-swoole2 為 PHP 增加 Swoole 功能,php-pecl-inotify 則是為了偵測檔案變動重新載入程式。


測試 laravel-swoole 及 Laravel-S

Google 和 Github 上,都是 swooletw/laravel-swoole 的關注度高很多,那就先測試 swooletw/laravel-swoole。

composer update 時發生錯誤,處理方式

使用個人使用者身分,進入 docker 中執行 composer

docker exec -it --user 1000:1000 docker_web_1 bash


在建立 Laravel 的 project 之後,依照 laravel-swoole 的說明修改 composer.json,然後執行 composer update,這時會出錯,錯誤訊息如下 
"Allowed memory size of 1610612736 bytes exhausted ... " 

參考網路找到的資訊
https://stackoverflow.com/questions/49212475/composer-require-runs-out-of-memory-php-fatal-error-allowed-memory-size-of-161

執行 composer update 時增加記憶體,成功安裝 PHP 的 Package

bash-4.2$ php -r "echo ini_get('memory_limit').PHP_EOL;"

128M

bash-4.2$ php -d memory_limit=-1 /usr/bin/composer update

然後依據說明,在命令列下指令啟動 swoole server 

php artisan swoole:http {start|stop|restart|reload|infos}

然後用瀏覽器瀏覽網頁,但是一直出錯。測試結果都是不成功,在讀取網頁時,一直出現下列錯誤

PHP Fatal error:  Call to undefined method Symfony\Component\HttpFoundation\ResponseHeaderBag::allPreserveCaseWithoutCookies() in /var/www/html/swoole_tst/vendor/swooletw/laravel-swoole/src/Server/Response.php on line 73

根據 google 到的資訊

allPreserveCaseWithoutCookies() is available after Symfony 3.4, what's your Laravel version?

Before Laravel 5.3, symfony/http-foundation is too old to use function allPreserveCaseWithoutCookies(). I'll try to make it compatible in the next release.

換了較舊版本的 laravel-swoole,或換較新版本的 Laravel,都不能成功,最後放棄。

第一次的測試碰到挫折,那就改為使用 hhxsv5/laravel-s 來測試。相對而言,laravel-s 較為麻煩,耐心的安裝設定後,依照說明下指令啟動 laravels,看到執行的畫面了,稍微了解運作方式之後,也可以在瀏覽器看到結果了。

bash-4.2$ php bin/laravels start

basePath: /var/www/html/swoole_tst/web-src 

VENDORDIR: /var/www/html/swoole_tst/web-src/../vendor

 _                               _  _____ 

| |                             | |/ ____|

| |     __ _ _ __ __ ___   _____| | (___  

| |    / _` | '__/ _` \ \ / / _ \ |\___ \ 

| |___| (_| | | | (_| |\ V /  __/ |____) |

|______\__,_|_|  \__,_| \_/ \___|_|_____/ 

                                           

Speed up your Laravel/Lumen

>>> Components

+---------------------------+--------------+

| Component                 | Version      |

+---------------------------+--------------+

| PHP                       | 7.0.33       |

| Swoole                    | 2.2.0        |

| LaravelS                  | 3.6.4        |

| Laravel Framework [local] | 5.1.46 (LTS) |

+---------------------------+--------------+

>>> Protocols

+-----------+--------+-------------------+----------------+

| Protocol  | Status | Handler           | Listen At      |

+-----------+--------+-------------------+----------------+

| Main HTTP | On     | Laravel Framework | 127.0.0.1:5200 |

+-----------+--------+-------------------+----------------+

>>> Feedback: https://github.com/hhxsv5/laravel-s

[2021-03-03 07:41:57] [TRACE] Swoole is running, press Ctrl+C to quit.


下面是 Laravel 5.1 的composer.json,只是多一行而已,為了保險起見,裝的 laravel-s 是前一版的。

{

    "name": "laravel/laravel",

    "description": "The Laravel Framework.",

    "keywords": ["framework", "laravel"],

    "license": "MIT",

    "type": "project",

    "require": {

        "php": ">=5.5.9",

        "laravel/framework": "5.1.*",

        "hhxsv5/laravel-s": "3.6.*"

    },

    "require-dev": {

        "fzaninotto/faker": "~1.4",

        "mockery/mockery": "0.9.*",

        "phpunit/phpunit": "~4.0",

        "phpspec/phpspec": "~2.1"

    },

    "autoload": {

        "classmap": [

            "database"

        ],

        "psr-4": {

            "App\\": "app/"

        }

    },

    "autoload-dev": {

        "classmap": [

            "tests/TestCase.php"

        ]

    },

    "scripts": {

        "post-root-package-install": [

            "php -r \"copy('.env.example', '.env');\""

        ],

        "post-create-project-cmd": [

            "php artisan key:generate"

        ],

        "post-install-cmd": [

            "Illuminate\\Foundation\\ComposerScripts::postInstall",

            "php artisan optimize"

        ],

        "post-update-cmd": [

            "Illuminate\\Foundation\\ComposerScripts::postUpdate",

            "php artisan optimize"

        ]

    },

    "config": {

        "preferred-install": "dist",

        "vendor-dir": "../vendor"

    }

}

在 laravel-s  的 git 專案網頁中,相關的說明蠻細的,一下子吸收不了那麼多,其中有一段是使用 httpd 的 reverse-proxy 來提供服務的說明,就照著設,內容大致如下,可以正常運作,但不盡完美,等後面測試累積較多經驗後,再來整理說明。

ProxyRequests Off


<Proxy *>

Order allow,deny

Allow from all

</Proxy>


# ProxyVia On


ProxyPass /swoole-web http://127.0.0.1:5200

ProxyPassReverse /swoole-web http://127.0.0.1:5200


初步測試後的心得

初步測試後,認為在使用上有一些要處理的問題,如下

  • 使用 url() 和 asset() 產生的 url 都是 http://127.0.0.1:5200 開頭
  • 只能處理透過 index.php 產生的網頁,assets 下的,如圖檔,js,css檔,都不能讀取
  • dump(),tracy debugger 等都不能運作
  • 依據 hhxsv5/laravel-s 的提示,必須使用 request,response 來處理輸入/輸出
目前的結論是,假如很在乎效能,就必須大幅調整程式,才能使用。另外,簡單的測試,原來的網頁存取次數 460.83 trans/sec,使用 swoole 加速後 1851.85 trans/sec,約 4倍,很爽的飆速感覺。

後續報告,經過 2 個多星期的奮鬥之後,想法有一些改變,可以在進入 kernel 的服務之前,預做一些處理,程式要改動部份就很少了。

沒有留言:

張貼留言

網誌存檔