众所周知,workerman是基于php cli的,由于php cli模式下无法使用php自带的header、sesion、cookie等函数,这导致将传统的php项目无法直接在workerman容器下直接运行。
我一度以为让传统业务在workerman中运行,就必须更改框架甚至业务代码以适配workerman,直到joanhey发了一个issue,打破了我的认知。
他们发布了一个名叫AdapterMan的项目,它可以做到不更改传统框架代码的情况下让你的传统php项目放到workerman中正常运行,并且他们公司已经在生产环境用了2年。
注意,是零代码改动直接让laravel、lumen、Slim等框架的项目在workerman上运行。
目前他们已经在laravel、lumen、Slim、Symfony、CakePHP、Yii2、KumbiaPHP 等做了初步压力测试,性能有很大的提升。
以下是压测结果
Fw | Plaintext | Json | Single query | Multiple query | Updates | Fortunes |
---|---|---|---|---|---|---|
Laravel | 14,799 | 14,770 | 9,263 | 3,247 | 1,452 | 8,354 |
Laravel Roadrunner | 482 | 478 | 474 | 375 | 359 | 472 |
Laravel Swoole | 38,824 | 37,439 | 21,687 | 3,958 | 1,588 | 16,035 |
Laravel Laravel s | 54,617 | 49,372 | 23,677 | 2,917 | 1,255 | 16,696 |
Laravel Workerman | 103,004 | 99,891 | 46,001 | 5,828 | 1,666 | 27,158 |
Laravel with Workerman % gain | 596.02% | 576.31% | 396.61% | 79.489% | 14.738% | 225.09% |
Fw | Plaintext | Json | Single query | Multiple query | Updates | Fortunes |
---|---|---|---|---|---|---|
Symfony | 38,231 | 37,557 | 12,578 | 10,741 | 3,420 | 10,741 |
Symfony Workerman | 210,796 | 197,059 | 107,050 | 13,401 | 4,062 | 71,092 |
Fw | Plaintext | Json | Single query | Multiple query | Updates | Fortunes |
---|---|---|---|---|---|---|
Lumen | 18,998 | 18,616 | 10,791 | 3,496 | 1,461 | 9,223 |
Lumen Swoole | 44,861 | 43,598 | 24,255 | 4,178 | 1,599 | 16,854 |
Lumen Laravel s | 93,335 | 82,745 | 31,567 | 3,030 | 1,282 | 21,130 |
Lumen Workerman | 185,126 | 177,667 | 58,729 | 5,857 | 1,662 | 31,430 |
Without ORM
Framework | JSON | 1-query | 20-query | Fortunes | Updates | Plaintext |
---|---|---|---|---|---|---|
Slim 4 | 38,305 | 34,272 | 12,579 | 32,634 | 2,097 | 35,251 |
Slim 4 Workerman | 129,393 | 81,889 | 15,803 | 73,212 | 2,456 | 134,531 |
Slim 4 Workerman pgsql * | 102,926 | 19,637 | 92,752 | 14,875 |
Lumen v9
接入代码类似
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Adapterman\Adapterman;
use Workerman\Worker;
Adapterman::init();
$http_worker = new Worker('http://0.0.0.0:8080');
$http_worker->count = 8;
$http_worker->name = 'AdapterMan';
$http_worker->onWorkerStart = static function () {
//init();
require __DIR__.'/start.php';
};
$http_worker->onMessage = static function ($connection, $request) {
$connection->send(run());
};
Worker::runAll();
项目地址:
https://github.com/joanhey/AdapterMan 强烈建议大家为其点赞(点星星)
相关链接:
https://github.com/walkor/workerman/issues/824
先顶为敬
Yii2的测试呢?
所有的PHP框架测试都在这里:https://github.com/joanhey/FrameworkBenchmarks/tree/master/frameworks/PHP
学习了!
赞!已经响应号召送上星星。^_^
🐂🍺
老大,不行哇,我拿着 laravel 项目测试运行,静态资源没成功加载到,laravel 的 缓存使用了 phpredis,提示找不到 Redis。
而且根据 workerman 文档写的响应静态文件,因为版本依赖过低,导致无法使用 (new Response)->withFile(); 的方法进行处理。
https://github.com/joanhey/AdapterMan/issues/9
可以做到不更改传统框架代码的情况下让你的传统php项目放到workerman中正常运行,并且他们公司已经在生产环境用了2年。
然鹅官方和我说了 redis 作为 session 驱动时存在问题,正在排查ing?
占位
威武霸气
对于 dz wp等系统,有否办法直接使用,里面大量依赖 $_GET $_POST等,尤其是 dz 多个入口文件。
赞
https://github.com/TechEmpower/FrameworkBenchmarks/pull/7626/files#diff-e853be1cf6b848987afe860157bc6ed090ffe163e868fb96e7c515c787963e89
还是没看懂这么简单的一部分 怎么就ok了,目前看上去好像就是 初始化了request
他这个前置还有一个server.php的
原理是吧workerman当fpm使用,吧session,cookies等使用封装函数代替了,是个不错的想法,但是不能全部直接移植使用,还需要更改一些东西
看原理也不复杂,把一些相关方法替换了。
然后用
ob_get_clean();
获取对应框架的输出。他这个框架还没做到这个程度,应该只是适配了部分fpm的功能
同意
厉害
可以啊,希望webman的生态越来越好
我有点不相信不改代码,特别是引入其他库【抠鼻子】
牛
看起来是对 laravel tp6 这类封装较好的框架有效,如果拿来运行 dz dedecms 还是不行的
应该也可以,他这个思路是disable_function 掉自带函数,然后实现自己的函数。这么玩的话,框架基本上不存在跑起来的问题,问题是有些开发过程中的静态变量可能搞的内存泄漏。需要稍为调整下
迟来的赞
已star,因为这个帖子才注册的账号,来晚了~
php -c cli-php.ini server.php start 正常
php -c cli-php.ini server.php start -d 就报错
今天的版本应该不报个错了 作者的workman已经是4.1
我的修改 不知道影响不影响
我看到workman 4.* 已经修复了
webman和adaptman相当于是两种解决方案了吧,一种是当作fpm,一种是直接在fpm里写服务。性能应该还是webman好吧
这个怎么用啊,现有的项目直接composer require joanhey/adapterman?
牛逼,关注
如果可以完美兼容,感觉webman就不香了
还是webman香,性能、写法、和后面的各种组件看,还是webman还用
@walkor 这个功能应该官方来搞
laravel9 还测试到两个问题 一个静态文件加载失败
第二个上传图片失败
可能是workerman3.5的bug 希望能早点升级到4.*
对于laravel 应在请求时初使化一些laravel的单例,不初使化有可能会出现单例污染情况如:auth
在run中加入:$kernel->getApplication()->forgetInstance('auth');
依次类推荐!
没看懂咋用
有没有大佬分析下这个实现原理是啥呢?
我在使用redis-queue,用的是workerman 4.*,希望早日升级到workerman 4.0,让我试试。
对于laravel 应在请求时初使化一些laravel的单例,不初使化有可能会出现单例污染情况如:auth如果不重置,会导致登陆后,
返回的是第一个登陆的用户信息,
在run中加入:$kernel->getApplication()->forgetInstance('auth');如下,当然还有其它组件,用啥加啥
具体有多少单例是通过 判断变量返结果的,得大家使用中发现或者参考:swoole与laravel的整合了完善!
目前用于生产应核有点难,除非用的组件少,
加了
$kernel->getApplication()->forgetInstance('auth');
还是会污染 其他地方打开页面出现的是第一个的session
thinkphp6能用了么
thinkphp6 扩展库有tp官方推出的
今天可以用了
tp6咋用的
tp5能行吗
顶顶更健康
laravel 使用得自己加一条动态路由实现,静态路由会有一个问题:控制器中的 ,__construct 方法只会执行首次,路由也是按单例模式只初使化一次,要吗得按webman方法改变一下路由为每次初使化,当然不使用__construct魔术方法就好了
这个对低版本laravel很有用只是需要手动清理下单例那些,可以参考官方Octane扩展去清理,高版本直接用自带的官方扩展,或者有人已经出了workerman Octane的驱动了
HttpForPHP 我这个项目也是一样的 为什么就没有人关注下
使用workerman实现http服务,把现有其他框架的代码简单改为常驻内存http服务,未实现session支持,最适合用于接口服务,已有在yii项目中运行,参见自带的yii示例。
原理就是对PHP的$_SERVER $_COOKIE $_FILES $_REQUEST $_POST $_GET全局变量重置数据
$_SESSION太麻烦就没有处理 毕竟只针对接口应用的服务 所以就没有必要
主页:https://github.com/ncwsky/HttpForPHP
给你一个star
3q
充分说明了:不管再好的项目,没有详细清晰的文档,也难以吸引关注。
至少要写出这个项目的使用场景、解决的问题、如何在项目中引用,比如laravel中、lumen中或者其他三方项目中如何接入
你这个有项目在跑吗?如果接入,是不是也是零修改?
哈哈,零修改,基本是跑起来了。回头试下压测看看效果
项目的yii示例就是在线运行的 通过nginx匹配符合的请求代理到服务里处理
零修改 不现实 针对自定义的header http_code还是需要处理的 就像yii那个示例里的一样
file_get_contents('php://input')这个卡住了,,像微信支付回调都是用这个接收的,你是怎么搞的?不会都类库都自己处理一下吧??
这是我yii项目里easywechat库我的处理方式 仅供参考
$app = Factory::officialAccount($config);
$app->request = WeixinRequest::createFromGlobals(); //重置wx的request
$app->request->setContent(\Yii::$app->request->getRawBody()); //常驻内存时推送内容置入
文件上传是不是需要单独处理啊,其他的都没有问题,就是上传文件这个地方不管用
thinkphp6咋用的啊
我尝试了一下适配现有项目,现有项目使用的lumen,发现http post body 里面的值,在lumen 的$request对象里获取不到,是我使用姿势不对吗?
$request 在有些地方获取不到,不过你可以换成 request() 就获取到了
试了一下,还是不行的。看起来有些地方还是有问题,没办法直接用
参考Octane扩展,入口去初始化request即可
看了下,骚操作呀,应该是可以适配任意项目,本质就直接禁止掉部分系统函数,手动实现去适配
最大的障碍就是静态引用。
所以说
零代码改动
是不可能的。这个需要php8 老项目版本一般比较低,会兼容吗?
只有PHP8以上才可以重写系统函数
不明所以,随便看看
thinkphp6 加速失败 各种报错...
安装报错 composer require joanhey/adapterman
是我用tp6,已经安装过workerman了,版本较高
tp5可以用吗
没用过,现在tp6 + 8.1 还是不能用,启动会报错,没继续弄这个了
牛逼的项目
Test environment:
Mac 13.3.1
Workerman version:4.1.5
PHP version:8.1.17
Event-Loop:\Workerman\Events\Select
Adapterman: 0.6.1
Laravel : 9.33.0
当我运行
php server.php start
时是可正常使用的,但是当我运行php server.php start -d
在访问接口的时候就报错了,错误在这个帖子里。https://github.com/joanhey/AdapterMan/issues/36
我现在的疑问是 workerman的守护模式和非守护模式有什么不一样的地方?不知道有没有人遇到这样的问题
laravel 文件上传处理,更改原码中 http.php 500行,下面的switch部分为:
php7.X 能跑吗?装了一下提示PHP版本不兼容,看了一下貌似要 PHP8 以上
不可以。因为php8 支持 disable_function 的函数重新定义。在8之前会报错。
唯一的问题: 代码创建的 静态变量 怎么解决?如何一键清理所有静态变量?
这个没得搞,就怕静态 数组 无限添加 必然内存泄露
实现不了吗,一键删除所有静态变量?
需要老大修改一下workerman,来解决内存泄漏的问题
$http_worker->onMessage = static function ($connection, $request) {
$connection->send(run());
};
这里onMessage 需要改一下。增加一个控制的开关:实现每次收到消息后都用新进程处理,解决静态变量、内存泄漏的问题:
方法:
onWorkerStart执行一些需要提前加载的代码之后,worker进程提前fork出很多子进程备用,
然后每次 onMessage 接收到消息都用fork出的进程处理,用完就销毁,同时fork一个新的。
其中涉及到信号的处理,fork出的进程如何接收数据和主进程通讯等
看时间节点,已经使用两年半了,哈哈哈哈
明天试试在Thinkphp6或者8上面是什么效果
加速的话对服务器内存要求是多少呀,资源消耗会很大嘛
内存占用会比php-fpm 少很多的。对比那些php-fpm开很多的服务来说