无需修改任何代码和扩展将你的Laravel项目性能提高20倍
2024-08-02日补充
- 最新文档地址: ripple.cloudtay.com/
- 兼容性更新已支持PHP8.1+
-
特性更新已支持自我守护模式运行
正文
我要分享一个令人激动的黑科技:这个项目能够在无需修改任何代码且无需第三方扩展的前提下,将你的 Laravel 项目性能提高 20倍。它仅依赖于 PHP 原生的 pcntl
、posix
、fiber
和 sockets
。
项目灵感
起因是看到官方发布的 PHP 8.1 更新中引入了 fiber 特性,看到这则消息时我非常激动,我仿佛看到了 PHP 的更多可能性。再结合我对Swoole 和 Workerman 的工作流程了解得出结论:它能够完美应用到 Laravel 和 ThinkPHP 等这些规范的面向对象标准框架中。
思路
我的思路是通过利用 fiber 特性,将 Laravel 项目中的 I/O 操作异步化,从而减少阻塞时间,提高整体性能。具体方法包括以下几个方面:
- 利用 fiber 实现协程:将传统的同步 I/O 操作改为异步 I/O 操作,使得 PHP 代码能够在等待 I/O 操作时执行其他任务。
- 集成到现有框架:在不修改现有业务逻辑代码的前提下,通过中间件或扩展包的形式,将新的异步 I/O 操作集成到 Laravel 项目中。
- 优化资源利用率:通过减少阻塞时间,提高服务器的并发处理能力,从而提升整体性能。
- 提供更多协程助手:提供更多的协程助手函数,方便开发者使用协程特性。
- 借鉴了async/await特性:借鉴了JavaScript中的async/await特性,提供了类似的函数,方便开发者编写异步代码。
结果
经过一系列的测试和优化,这个项目最终成型,到目前为止我已经在生产环境中部署且能够在 Unix/Linux 服务器上正常工作,以下为性能对比结果:
同时该项目的安装流程也非常简单
安装方法
通过 Composer 安装
composer require cclilshy/p-ripple-drive
运行
php artisan p:run
# -l | --listen 服务监听地址,默认为 http://127.0.0.1:8008
# -t | --threads 服务线程数,默认为4`
Nginx 伪静态配置
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
不出意外应该是这样的运行结果:
至此,你的工作已经完毕,无需进行额外配置,但仍然需要有一定了解 CLI运行模式的机制,并知悉下列函数在运行过程中会发生什么以决定如何使用它们,如 dd
、var_dump
、echo
、exit
、die
。如果你的项目中充斥了
header('content-type: application/json');
die(json_encode($data));
这样的写法则不适用于该项目
更多
该项目不仅提供了性能提升,还提供了多个协程助手以让开发者能够充分利用协程的特性。当然你也可以忽略这一项。如你可以在控制器中做这些事:
特性 defer
public function index(Request $request) : string {
\P\defer(function(){
//TODO: 这里的代码将在 return 之后运行, 允许返回请求后做某些事情
});
return 'Hello PRipple';
}
特性 await
public function index(Request $request) : string {
// 非堵塞进程模式读取某个文件
$content = \P\await(
\P\IO::File()->getContents(__FILE__)
);
return $content;
}
特性 组件原生化
PRipple 不会干涉组件的规范,你可以使用任何你喜欢的组件,并得到预期的结果。如以下例子将得到 GuzzleHttp
的标准 Response 对象:
public function index(Request $request) : string {
// 非堵塞进程模式请求某个 URL
$response = \P\await(
\P\Net::Http()->Guzzle()->getAsync('http://www.baidu.com')
);
return $response;
}
附言
目前,该项目已经支持 ThinkPHP 和 Laravel。未来我计划将它扩展到更多的 PHP
框架中。尽管该项目在我的服务器上完全正常工作,我甚至觉得它很完美,但依然可能有意料之外的Bug需要发现。期待大家在使用过程中反馈问题,共同完善这个项目。也欢迎大家参与到项目的开发和优化中,共同推动
PHP 生态的发展。如果你想了解它是怎么工作的以及更多的使用方法欢迎查阅文档:
项目驱动: github.com/cloudtay/p-ripple-drive
项目核心: github.com/cloudtay/p-ripple-core
项目交流
群聊直通车 | 作者微信(邀请入群) |
---|---|
![]() |
![]() |
我特地建了个交流群以供各位交流,欢迎通过添加我本人微信 jingnigg 进入交流群
高认可度评论:
PHP很久没看到这么新颖得东西了
PHP很久没看到这么新颖得东西了
有什么弊端吗?
不错,不错!!!有一个问题,这里如何处理原生的阻塞请求例如 PDO,Redis
不懂,但觉得牛逼。我觉得目前急需你这个的是filament。filament的速度有些慢。
请教下 和使用 octane 有什么不同?
这是一个令人激动的项目,Laravel 项目直接引入进来作为服务,就能直接改善性能。
不过有个疑问的地方,Webman 引入这个工具,能改善的地方是什么?
它(webman)本身也是非阻塞IO,性能提升应该大差不差,是否可以理解为 引入之后,可以编写非阻塞式代码,能支持异步代码?
关注一下
所以,怎么再后台运行呢
不错
赞👍 看起来是快了不少, 看这个对比有个疑问, laravel fpm下的接口900ms左右 应该是没有做优化的吧 opencache开了吗 laravel各种缓存配置优化了吗? 第一个接口看样子是获取某个分类 开了的话不至于会这么慢 我司laravel 接口基本上都在100ms左右 强制要求200ms以内..........
确实不错,跟octane类似,这种常驻式的对单例模式有点影响。
你这个貌似要php8.3以上,我还是octane swoole4 PHP8.0 搭配laravel8,目前运行也还好。
大佬 金融相关的项目吗
只能说牛逼
mark
能不能做到跟webman一样,可以加个 -d 自己守护进程启动,用第三方启动真的好麻烦,而且经常不知道什么原因占满内存
你这升级后,会有幻读,脏读
sh-4.2# php artisan p:server stop
^C
sh-4.2# php artisan p:server status
^C
我在本地docker里跑,这个两个命令都会无响应
关注下新东西
建议适配一下octane
mark
支持一波
ThinkPHP 一直没试成功,mac tp8 swoole-cli
不错,好东西。
大佬,牛逼,已star
来催更了,大佬款支持8.1
本来打算在一个小项目中用一下,调试也成功了 但是对于不停进行的请求没有时间限制或者返回状态码 小型服务器会宕机。php-fpm跑来就没这个问题 希望楼主可以考虑下这方面
@cclilshy 楼主得空做下压测看,我压测的时候发现总是会随机有一些连接会被丢失,nginx上会502或者504,造成有一定的错误率。用frankenphp的话性能虽然没pripple好,但是错误率为0,稳定性感觉还是有点问题。
好久没发言了,特意登陆账号上来给楼主点个赞。加油。
主要问题还是那些库基本都是阻塞式,然后就没有然后了
静态文件会报404,必须配合nginx做伪静态?
加油
@稻草人AQA @PHP布道者 @aab @shebaoting @techutter @yangweijie @gyp719 @bigbug-gg @滚球兽进化 @MArtian @wongvio @goodgood @Noctis @Alone88 @putyy @33qis @miyama1984 @tongfei @如此甚好 @随波逐流 @zend @wongvio @qianfan @leirhy @star7th @ltaoo @pasawu @goodgood @yangweijie @空山 @chouxuka @yongqiangdou @lidongyoo @tsingyan @luscio @xcz196
感谢各位同学的关注与支持,该项目已在一周前发布了第一个经过生产环境测试30天的稳定版本,为更及时的解决/更近开发过程中出现的疑问,我特地建了个交流群以供各位交流,欢迎通过添加我本人微信
jingnigg
进入交流群学习了,可以水平不够看不懂
支持DCAT吗?
mark一记 努力学习
不能 dd 了,那 xdebug 可以用吗