deepziyu / yii2-swoole
full solutions making yii2-framework run on swoole with coroutine
Installs: 192
Dependents: 1
Suggesters: 0
Security: 0
Stars: 88
Watchers: 5
Forks: 16
Open Issues: 3
Requires
- php: >=7.0.13
- yiisoft/yii2: ~2.0.9
- yiisoft/yii2-redis: ~2.0.0
Requires (Dev)
- eaglewu/swoole-ide-helper: dev-master
- swoft/http-client: dev-master
This package is not auto-updated.
Last update: 2025-03-02 07:42:54 UTC
README
为赋予 Yii2 框架协程异步能力而生。
后期开发会依赖 Swoft 框架 去实现功能,相信 Swoft 会是下一代优秀的框架。
此插件基于 swoole (v2.0) 底层实现的协程,改造 Yii2 的核心代码,使开发者无感知,以及在不改动业务代码的情况下,用上 swoole 的异步IO能力。
特性
-
协程 MySQL 客户端、连接池,支持主从、事务。
-
协程 Redis 客户端、连接池、缓存 (目前未打算支持事务)
-
协程 HttpClient , 依赖于 Swoft 实现
-
swoole_table 缓存组件
-
异步文件日志组件
-
业务代码和 swoole 主进程分离
安装
环境要求
- hiredis
- composer
- PHP7.X
- Swoole2.1 且开启协程和异步 Redis
swoole install
composer install
- 在项目中的
composer.json
文件中添加依赖:
{ "require": { "deepziyu/yii2-swoole": "*" } }
- 执行
$ php composer.phar update
或$ composer update
进行安装。
配置
你可以参考 这个示例项目
新建一个启动文件即可。
启动文件清晰的展现出本插件的工作、流程原理。动手写这个文件有助于你更加理解本插件。
swoole.php 示例如下:
defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); defined('WEB_ROOT') or define('WEB_ROOT', dirname(__DIR__) . '/web'); //web目录的路径,用户访问的静态文件都放这里 require(__DIR__ . '/../../vendor/autoload.php'); $config = [ 'id' => 'api-test-hello', 'setting' => [ // swoole_server 的配置。 // @see 其他配置项见 https://wiki.swoole.com/wiki/page/274.html 'daemonize'=>0, 'worker_num'=>2, 'task_worker_num' => 1, 'log_file' => __DIR__.'/../runtime/logs/swoole.log', 'log_level'=> 0, 'chroot' => '/', ], 'cacheTable' => function (){ // swoole_table 需要提前启动,大小为 2 的次方 return deepziyu\yii\swoole\cache\SwooleCache::initCacheTable(1024); }, 'bootstrap' => [ 'class' => 'deepziyu\yii\swoole\bootstrap\YiiWeb', 'config' => function(){ // 用闭包是为了延迟加载 // 返回 Yii 的各个组件的配置 require_once(__DIR__ . '/../../vendor/autoload.php'); require_once(__DIR__ . '/../../yii-swoole/Yii.php'); require(__DIR__ . '/../config/bootstrap.php'); $config = yii\helpers\ArrayHelper::merge( require(__DIR__ . '/../config/main.php'), require(__DIR__ . '/../config/main-local.php'), [ 'components' => [ 'errorHandler' => [ 'class'=>'deepziyu\yii\swoole\web\ErrorHandler' ], 'cache' => [ 'class' => 'deepziyu\yii\swoole\cache\SwooleCache', ], ], ] ); return $config; }, ], ]; // 配置了这么多,最终还是逃不过一 run() deepziyu\yii\swoole\server\Server::run($config);
启动
php swoole.php start|stop|reload|reload-task
Usage HttpClient
HTTP 客户端的使用请参考 Swotf 文档。
TODO
- MysqlPool 目前不支持事务 (transaction)。 ( 已实现 )
- MysqlPool、RedisPool 连接池用满了,目前是用 sleep() 进行排队等待,超过等待次数后,报异常。
- MysqlPool 目前不支持主从。 ( 已实现 )
已知Bug
-
迭代器将导致协程挂起。
BUG代码:
$models = User::find()->each(10); foreach ($models as $model) { // Hang up in this row $data[] = $model->toArray(); }
已解决Bug
-
new ActiveRecord([]); 中会触发 __set() 魔术方法中调用协程Client,导致两个问题:
1、 首次实例化会导致协程挂起。
2、 如果 SQL 报错直接导致 work 进程终止。
BUG代码:
class OneModel extend ActiveRecord{ public static function tableName() { return 'some-table do not exist'; } } //导致进程终止 $model = new OneModel([ 'some-att'=>'some-value', ]);
链接
Chat && Help
Swoft 框架QQ交流群:548173319