使用swoole改造laravel应用
标签(空格分隔): php
1. 概述
1.1 swoole介绍
Swoole 是为 PHP 开发的生产级异步编程框架。 他是一个纯 C 开发的扩展, 他允许 PHP 开发者在 PHP 中写 高性能,可扩展的并发 TCP, UDP, Unix socket, HTTP, WebSocket 服务, 而不需要拥有太多的非阻塞 I/O 编程和低级别的 Linux 内核知识。 你可以把 Swoole 想象成 Go, 但对于 PHP 来说将有更高性能。
1.2 为什么要在 Swoole 上运行 Laravel?
在PHP的生命周期中, 当你每次运行PHP脚本的时候, PHP都需要初始化模块并为你的运行环境启动zend引擎. 并将PHP脚本编译为OpCodes
以便Zend
引擎执行.
但是, 这样的生命周期需要在每次请求的时候都执行一遍, 因为单个请求创建的环境在请求结束后立即销毁.
换句话说, 在传统的PHP生命周期中, 为了脚本执行而浪费了大量的时间去创建和销毁资源. 想象一下像laravel这样的框架, 在每次请求中需要加载多少文件? 同时也浪费了大量的I/O操作.
swoole是内置在应用级别的server, 并且所有脚本文件在加载一次之后便可以保存在内存中. 这就是为什么我们需要尝试在swoole上运行laravel.
swoole可以提供强大性能而Laravel则可以提供优雅代码结构. 完美!
2. 准备工作
app | php | laravel | swoole |
---|---|---|---|
7.1.16 | 5.4.36 | 4.1.2 |
2.1 wrk
基准测试工具:
// 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/repositoriesRUN 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 的主要特点:
- 在 Swoole 运行 Laravel/Lumen 应用
- 出色的性能提升至 30x
- 沙盒模式隔离应用程序容器
- 支持在 Laravel 应用中运行 WebSocket 服务器
- 支持 协议
- 支持 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
来进入 Laravel 应用。
如果需要修改端口号或服务地址, 可配置相应的环境变量
// vendor/swooletw/laravel-swoole/config/swoole_http.phpSWOOLE_HTTP_HOST: '127.0.0.1'SWOOLE_HTTP_PORT: '1215'复制代码
详细的文档参考:
3.2 基于 FPM + Nginx 的测试结果
wrk -t4 -c100 http://your.domain.com/versionRunning 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 readRequests/sec: 285.63Transfer/sec: 289.79KB复制代码
wrk -t12 -c400 -d30s http://your.domain.com/versionRunning 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 132Requests/sec: 478.09Transfer/sec: 484.34KB复制代码
3.3 Swoole HTTP 服务的测试结果
wrk -t4 -c100 http://your.domain.com/versionRunning 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 25Requests/sec: 893.71Transfer/sec: 801.26KB复制代码
wrk -t12 -c400 -d30s http://your.domain.com/versionRunning 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 619Requests/sec: 793.04Transfer/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; }}复制代码