使用swoole改造laravel應用

使用swoole改造laravel應用

標籤(空格分隔): phpphp


1. 概述

1.1 swoole介紹

Swoole 是爲 PHP 開發的生產級異步編程框架。 他是一個純 C 開發的擴展, 他容許 PHP 開發者在 PHP 中寫 高性能,可擴展的併發 TCP, UDP, Unix socket, HTTP, WebSocket 服務, 而不須要擁有太多的非阻塞 I/O 編程和低級別的 Linux 內核知識。 你能夠把 Swoole 想象成 Go, 但對於 PHP 來講將有更高性能。html

1.2 爲何要在 Swoole 上運行 Laravel?

clipboard.png

在PHP的生命週期中, 當你每次運行PHP腳本的時候, PHP都須要初始化模塊併爲你的運行環境啓動zend引擎. 並將PHP腳本編譯爲OpCodes以便Zend引擎執行.linux

可是, 這樣的生命週期須要在每次請求的時候都執行一遍, 由於單個請求建立的環境在請求結束後當即銷燬.nginx

換句話說, 在傳統的PHP生命週期中, 爲了腳本執行而浪費了大量的時間去建立和銷燬資源. 想象一下像laravel這樣的框架, 在每次請求中須要加載多少文件? 同時也浪費了大量的I/O操做.laravel

swoole是內置在應用級別的server, 而且全部腳本文件在加載一次以後即可以保存在內存中. 這就是爲何咱們須要嘗試在swoole上運行laravel.git

swoole能夠提供強大性能而Laravel則能夠提供優雅代碼結構. 完美!github

2. 準備工做

app php laravel swoole
your.domain.com 7.1.16 5.4.36 4.1.2

2.1 wrk

基準測試工具:wrkdocker

// wrk命令參數
-c, --connections: total number of HTTP connections to keep open with
                   each thread handling N = connections/threads

-d, --duration:    duration of the test, e.g. 2s, 2m, 2h

-t, --threads:     total number of threads to use

-s, --script:      LuaJIT script, see SCRIPTING

-H, --header:      HTTP header to add to request, e.g. "User-Agent: wrk"

    --latency:     print detailed latency statistics

    --timeout:     record a timeout if a response is not received within
                   this amount of time.

2.2 php-swoole安裝

pecl install swoole編程

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    && sed -i 's/nl.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache --virtual .build-deps \
        $PHPIZE_DEPS \
    && docker-php-source extract \
    && cd /usr/src \
    && wget http://pecl.php.net/get/swoole-4.1.2.tgz \
    && tar -xzvf swoole-4.1.2.tgz \
    && mv /usr/src/swoole-4.1.2 /usr/src/php/ext/swoole \
    && docker-php-ext-configure swoole --enable-openssl \
    && docker-php-ext-install swoole \
    && runDeps="$( \
        scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
            | tr ',' '\n' \
            | sort -u \
            | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
      )" \
      && apk add --no-cache --virtual .php-rundeps $runDeps \
    && docker-php-source delete \
    && apk del .build-deps \
    && rm -rf /usr/src/swoole-4.1.2.tgz

2.3 laravel-swoole 擴展安裝

如下是 swooletw/laravel-swoole 的主要特色:bootstrap

  • 在 Swoole 運行 Laravel/Lumen 應用
  • 出色的性能提高至 30x
  • 沙盒模式隔離應用程序容器
  • 支持在 Laravel 應用中運行 WebSocket 服務器
  • 支持 Socket.io 協議
  • 支持 Swoole 表跨進程共享

使用 Composer 安裝:

$ composer require swooletw/laravel-swoole

2.4 laravel/lumen配置

這個包支持包自動發現機制。若是你運行 Laravel 5.5 以上版本,你能夠跳過這一步。

laravel配置: 在 config/app.php 服務提供者數組添加該服務提供者

[
    'providers' => [
        SwooleTW\Http\LaravelServiceProvider::class,
    ],
]

lumen配置: 請將下面的代碼添加到 bootstrap/app.php

$app->register(SwooleTW\Http\LumenServiceProvider::class);

3. 基準測試數據

3.1 創建並運行起來

如今,你能夠執行如下的命令來啓動 Swoole HTTP 服務。

php artisan swoole:http start

而後你能夠看到如下信息:

Starting swoole http server...
Swoole http server started: http://127.0.0.1:1215

如今能夠經過訪問 http://127.0.0.1:1215 來進入 Laravel 應用。

若是須要修改端口號或服務地址, 可配置相應的環境變量

// vendor/swooletw/laravel-swoole/config/swoole_http.php
SWOOLE_HTTP_HOST: '127.0.0.1'
SWOOLE_HTTP_PORT: '1215'

詳細的文檔參考: https://wiki.swoole.com/wiki/page/14.html

3.2 基於 FPM + Nginx 的測試結果

wrk -t4 -c100 http://your.domain.com/version

Running 10s test @ http://your.domain.com/version
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   341.64ms  108.70ms 801.47ms   69.08%
    Req/Sec    71.72     27.35   171.00     65.57%
  2864 requests in 10.03s, 2.84MB read
Requests/sec:    285.63
Transfer/sec:    289.79KB
wrk -t12 -c400 -d30s http://your.domain.com/version

Running 30s test @ http://your.domain.com/version
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   801.35ms  349.89ms   2.00s    68.56%
    Req/Sec    40.61     19.83   126.00     65.80%
  14390 requests in 30.10s, 14.24MB read
  Socket errors: connect 0, read 0, write 0, timeout 132
Requests/sec:    478.09
Transfer/sec:    484.34KB

3.3 Swoole HTTP 服務的測試結果

wrk -t4 -c100 http://your.domain.com/version

Running 10s test @ http://your.domain.com/version
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   198.64ms  324.54ms   1.96s    88.59%
    Req/Sec   225.62     91.30   430.00     62.72%
  9021 requests in 10.09s, 7.90MB read
  Socket errors: connect 0, read 0, write 0, timeout 25
Requests/sec:    893.71
Transfer/sec:    801.26KB
wrk -t12 -c400 -d30s http://your.domain.com/version

Running 30s test @ http://your.domain.com/version
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   319.84ms  398.59ms   2.00s    85.59%
    Req/Sec    66.94     35.58   240.00     66.09%
  23862 requests in 30.09s, 20.89MB read
  Socket errors: connect 0, read 0, write 0, timeout 619
Requests/sec:    793.04
Transfer/sec:    711.05KB

4. 問題&注意事項

  • php7只能用swoole 4.0+ 版本

4.1 靜態文件使用swoole性能是否受到影響?

使用Nginx來代理運行於Swoole上的Laravel

server {
    listen 80;
    server_name your.domain.com;
    root /path/to/laravel/public;
    index index.php;
    location = /index.php {
        # Ensure that there is no such file named "not_exists"
        # in your "public" directory.
        try_files /not_exists @swoole;
    }
    location / {
        try_files $uri $uri/ @swoole;
    }
    location @swoole {
        set $suffix "";
        if ($uri = /index.php) {
            set $suffix "/";
        }
        proxy_set_header Host $host;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # IF https
        # proxy_set_header HTTPS "on";
        proxy_pass http://127.0.0.1:1215$suffix;
    }
}

5. 參考

相關文章
相關標籤/搜索