使用 Swoole 来加速你的 Laravel 应用
189

file

Swoole 是为 PHP 开发的生产级异步编程框架。 他是一个纯 C 开发的扩展, 他允许 PHP 开发者在 PHP 中写 高性能,可扩展的并发 TCP, UDP, Unix socket, HTTP, WebSocket 服务, 而不需要拥有太多的非阻塞 I/O 编程和低级别的 Linux 内核知识。 你可以把 Swoole 想象成 NodeJS, 但对于 PHP 来说将有更高性能。

为什么要在 Swoole 上运行 Laravel?

下图展示了 PHP 的生命周期。正如你所看到的那样,当你每次运行 PHP 脚本的时候,PHP都需要初始化模块并为你的运行环境启动Zend引擎。并且将 PHP 脚本编译为 OpCodes 以便 Zend引擎执行。

但是, 这样的生命周期需要在每次请求的时候都执行一遍。因为单个请求创建的环境在请求执行结束后会立即销毁。

换句话说, 在传统的 PHP 生命周期中, 为了脚本执行而浪费了大量的时间去创建和销毁资源。想象一下像 Laravel 这样的框架, 在每次请求中需要加载多少文件? 同时也浪费了大量的 I/O 操作
file

因此如果我们利用 Swoole 内置一个应用级别的 Server, 并且所有脚本文件在加载一次之后便可以保存在内存中呢? 这就是为什么我们需要尝试在 Swoole 上运行 Laravel。 Swoole 可以提供强大性能而 Laravel 则可以提供优雅代码结构使用。这俩儿真是完美组合 !

安装

以下是 swooletw/laravel-swoole 的主要特点:

  • 在 Swoole 运行 Laravel/Lumen 应用
  • 出色的性能提升至 30x
  • 沙盒模式隔离应用程序容器
  • 支持在 Laravel 应用中运行 WebSocket 服务器
  • 支持 Socket.io 协议
  • 支持 Swoole 表跨进程共享

使用 Composer 安装:

$ composer require swooletw/laravel-swoole

这个包依赖于 Swoole 。在使用这个包之前,请确保你的机器安装了正确的 Swoole 。使用下面的命令快速安装(linux):

pecl install swoole

在安装这个扩展之后,你需要编辑 php.ini 添加  extension=swoole.so

php -i | grep php.ini                      # check the php.ini file location
sudo echo "extension=swoole.so" >> php.ini  # add the extension=swoole.so to the end of php.ini
php -m | grep swoole                       # check if the swoole extension has been enabled

访问 官网 获取更多的信息。

注意:Swoole 现在只支持 Linux 和 OSX 。Windows 服务器现在还不支持。

然后,添加服务提供者:

如果你使用 Laravel ,在 config/app.php 服务提供者数组添加该服务提供者:

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

如果你使用 Lumen ,请将下面的代码添加到 bootstrap/app.php

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

这个包支持包自动发现机制。如果你运行 Laravel 5.5 以上版本,你可以跳过这一步。

建立并运行起来

现在,你可以执行以下的命令来启动 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 应用。

基准测试

使用 MacBook Air 13寸(2015年产)及干净的 Lumen 5.5 项目测试:
基准测试工具: wrk

wrk -t4 -c100 http://your.app

基于 FPM 的 Nginx

Running 10s test @ http://lumen.app:9999
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.14s   191.03ms   1.40s    90.31%
    Req/Sec    22.65     10.65    50.00     65.31%
  815 requests in 10.07s, 223.65KB read
Requests/sec:     80.93
Transfer/sec:     22.21KB

Swoole HTTP 服务

Running 10s test @ http://127.0.0.1:1215
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    11.58ms    4.74ms  68.73ms   81.63%
    Req/Sec     2.19k   357.43     2.90k    69.50%
  87879 requests in 10.08s, 15.67MB read
Requests/sec:   8717.00
Transfer/sec:      1.55MB

更多信息

在 Github Repo 查看官方包, 也可以参考 官方文档 获取更多信息。

此文最初发表于 Laravel News


Practice makes perfect.

原文地址:https://laravel-news.com/laravel-swoole?

译文地址:https://laravel-china.org/topics/10939/u...

本帖已被设为精华帖!
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 25
php -i | grep php.ini                      # check the php.ini file location
sudo echo "extension=swoole.so" > php.ini  # add the extension=swoole.so to the end of php.ini
php -m | grep swoole                       # check if the swoole extension has been enabled

应该是这个,用上面直接把配置文件覆盖掉了:

sudo echo "extension=swoole.so" >> php.ini 
4个月前

进来学习下..正好最近要搞swoole

4个月前
ziyanziyu

使用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;
    }
}
4个月前
Littlesqx
4个月前

@好好先森V5 您好,我是 laravel-swoole 的開發者 Albert,對於您提出的文檔對照,我承認該部分的文檔內容的確我是參照自您的專案文檔,若是這部分讓您不悅我願意向您致歉,或是您要讓我更正裡面任何文字也請告知,我這裡必定盡力配合。

但是如果您或是其他網友有分析過兩份專案的源代碼就會發現架構上有根本性很大的不同,"終於知道為什麼似曾相識"這句話似乎企圖誘導其他不了解的人認為我的專案是抄襲您的專案而來。

雖然說利用 Swoole 來加速 Laravel 這個概念上實作方法大方向差異不會太大,但無論是您或是我的專案也都不是第一個嘗試這樣做的人,而且兩邊專案目前發展方向也有所不同,想在此特別澄清,如果有比較過兩專案的建立時間還會發現我的時間是更早的。

附上我這裡專案完整的文檔:https://github.com/swooletw/laravel-swoole/wiki,有興趣的人仔細讀完之後便會了解我前面所說,您如果對於我文檔任何篇章覺得有可取之處,歡迎直接取用,也歡迎您可以使用我這邊專案的源代碼或任何觀念,反正專案本來就是基於 MIT 授權,我完全不會計較的。

另外我在其他介紹我專案項目的文章留言處也有發現您的蹤跡,發現您對於名聲似乎有一份執著在,我並不想特別與您競爭什麼,只是繼續發展我自己想投入的項目上而已。
http://www.cnblogs.com/johnson108178/p/8109596.html
https://twitter.com/laravelnews/status/992392293826093058

以上說明,不會再繼續針對任何底下的留言進行回覆,清者自清,我來繼續寫程式了。

4个月前

两方格局似乎高下立见呢...

4个月前

@albert_chen
Take easy 你理解的太严重了!

  • 我阐述了疑惑,你解答了,OK,那算完事。
  • 同属于Swoole生态,百花齐放是好事,期待你更加出色的项目。
4个月前
Summer

@Littlesqx
@albert_chen 说在前面,两位的项目都很赞,也都很大方地使用了 MIT License 进行开源,我很敬佩两位。

@albert_chen 文档参照了人家的,很正常嘛。而 @Littlesqx 不悦,换位思考,理解下对方啦。互相借鉴,才会有成长,感激他的成果的话,在 readme 里给个 ## Thinks to 也可。

@Littlesqx 既然已经使用了 MIT License,别人参考了下你的架构和文档,也未尝不可哈。

我认为,大家一起构建一个 积极的互助的 生态圈才是最重要的,因为这样我们才能有更多的人参与进来和更多的优质项目,最终受益的人都是我们每一个个体。我建议两位都在互相的文档里链接对方的项目,如 Spatie 经常在他们的项目 Readme 里加一个 Alternatives 区块,社区里认同的同学给我点个赞 :+1:

file

@duck0026
@好好先森V5

4个月前
Summer

@好好先森V5
@albert_chen 都是误会,不提也罢哈

4个月前

Hi @Summer , 感謝您的解說與回覆,我認為您提的 Alternatives 區塊概念很好,我願意加上 @好好先森V5 項目的連結表示致意

另外我其實也相當認同 @好好先森V5 專案中的許多代碼實踐,可能是我過度理解了,既是誤會,解開也就沒事了,也期待能與您在 Laravel 整合方面有其他的交流

4个月前

@Summer @albert_chen

4个月前
Littlesqx

看来是我多嘴了 :joy:

4个月前

@albert_chen 如何支持dingo/api的路由呢。二个包都封装了laravel的request和response...

4个月前
GhostCoder

这个包很好用我自己也在用,但是 session 会出问题 目前不知道怎么解决

3个月前

支持协程么

2个月前

按照文档配置了swool,nginx配置文件,https://github.com/swooletw/laravel-swoole/wiki/9.-Nginx-Configuration 但是网站所有链接都指向首页,
file

这里修改为
proxy_pass http://127.0.0.1:1215$suffix;
问题解决。

2个月前
1234561212122121121212

好像不能使用dd,报错500,但是日志不会记录

2个月前

swooleTW的lock怎么使用

file
第一个进程访问的时候,我故意放一个timer_after阻塞一下,10秒后会unlock。
然后第二个进程访问的时候,就直接卡住了,然后time out。。请问这样使用正确吗。@albert_chen @Summer

2个月前

各位好, 謝謝大家使用這個 package,因為我個人比較少造訪這個網站,也為了大家的問題能夠得到妥善的答覆,還麻煩各位至 Github 上依照格式直接開 issue(請各位盡量能使用英文,這樣可以讓更多不同國家的人一同參與討論),我看到 issue 有空就會回覆,再次謝謝大家的配合 :)

2个月前

不知道是不是我的测试方法有问题,本人测试的结果是使用 swoole http 服务 和 开启 opcache 的效果(请求耗时)基本一致
下面是一些测试结果:
file
测试的环境是 1核1G 阿里云,php7.1.7
本人本地 ab 测试的时候,数据也是非常的好看的,上面的测试结果是阿里云的 PTS 测的

2个月前
fatrbaby

有上生产环境的么?

2个月前

@ruby 加速php运行原理上,我也感觉是一样的,都是缓存PHP文件,下次运行时调用内存里的文件。

2个月前

测试了几天,高并发应用用着挺好,但是涉及到高运算的时候,慢的要命。

1个月前
Abyss1st
    • 感觉和慕课网的singwa老师讲的好像。。 :+1:
1个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!