目录

1. 说明:

2. 要求:

3. 实现原理:

4. 实现:

4.1 目录结构

4.2 守护进程服务命令行

4.3 任务

4.4 服务运行示例


1. 说明:

众所周知,Yii2是集优雅与效率于一身的框架,EasySwoole则对Swoole做了人性化的使用包装,两者融合并提供守护应用服务,这里分享我的实践例子。

2. 要求:

1. 在Yii控制台下启动,兼容EasySwoole的种种特性

2. 能正确调取Yii中所有的模型类、组件等等

3. 多进程执行消息处理任务,长时运行稳定

3. 实现原理:

  • 设置守护程序应用(daemon)路径,easyswoole将在这个应用路径下运行
  • 添加 console/EasySwooleController

4. 实现:

4.1 目录结构

  • daemon为EasySwoole实际运行目录
  • daemon/dev.php 为easyswoole配置
  • daemon/log 为easyswoole 运行时日子目录,同时console/runtime/logs为Yii日志目录,兼容

文件修改列表:

src\common\config\main.php - 定义easyswoole根目录

// setup easyswoole root to run task-server
defined('EASYSWOOLE_ROOT') or define('EASYSWOOLE_ROOT', PROJECT_ROOT . '/daemon');

src\daemon\dev.php

<?php/*** refer to https://www.easyswoole.com/QuickStart/config.html*/
return ['SERVER_NAME' => "EasySwoole",'MAIN_SERVER' => ['LISTEN_ADDRESS' => '0.0.0.0','PORT' => 9501,
//        'SERVER_TYPE' => EASYSWOOLE_WEB_SERVER, //可选为 EASYSWOOLE_SERVER  EASYSWOOLE_WEB_SERVER EASYSWOOLE_WEB_SOCKET_SERVER,EASYSWOOLE_REDIS_SERVER'SERVER_TYPE' => EASYSWOOLE_SERVER, //可选为 EASYSWOOLE_SERVER  EASYSWOOLE_WEB_SERVER EASYSWOOLE_WEB_SOCKET_SERVER,EASYSWOOLE_REDIS_SERVER'SOCK_TYPE' => SWOOLE_TCP,'RUN_MODEL' => SWOOLE_PROCESS,'SETTING' => ['worker_num' => 4,'reload_async' => true,'max_wait_time' => 3],'TASK' => ['workerNum' => 4,'maxRunningNum' => 128,'timeout' => 15]],'TEMP_DIR' => '/tmp','LOG' => ['dir' => EASYSWOOLE_ROOT . '/log', //日志文件存放的目录],'clientMqtt1' => [// for dev'clientConfig' => ['userName' => MQTT_DEFAULT_USER, // vhost+username = rabbitmq用户名'password' => RABBITMQ_DEFAULT_PWD, // 密码'clientId' => MQTT_SYS_CLIENT_ID1, // 客户端id1'keepAlive' => 30, // 默认0秒,设置成0代表禁用'protocolName' => 'MQTT', // 协议名,默认为MQTT(3.1.1版本),也可为MQIsdp(3.1版本)'protocolLevel' => 4, // 协议等级,MQTT3.1.1版本为4,5.0版本为5,MQIsdp为3'properties' => [], // MQTT5 中所需要的属性'delay' => 3000, // 重连时的延迟时间 (毫秒)
//            'maxAttempts' => 5, // 最大重连次数。默认-1,表示不限制'maxAttempts' => -1, // 最大重连次数。默认-1,表示不限制'swooleConfig' => ['open_mqtt_protocol' => true,'package_max_length' => 2 * 1024 * 1024]],'host' => RABBITMQ_DEFAULT_HOST,'port' => MQTT_DEFAULT_PORT,'appID' => 'clientMqtt1','appSecret' => 'public','publishUrl' => 'http://' . RABBITMQ_DEFAULT_HOST . ':15672/api/v4/mqtt/publish',],'clientMqtt2' => [// for app'clientConfig' => ['userName' => MQTT_DEFAULT_USER, // vhost+username = rabbitmq用户名'password' => RABBITMQ_DEFAULT_PWD, // 密码'clientId' => MQTT_SYS_CLIENT_ID2, // 客户端id1'keepAlive' => 30, // 默认0秒,设置成0代表禁用'protocolName' => 'MQTT', // 协议名,默认为MQTT(3.1.1版本),也可为MQIsdp(3.1版本)'protocolLevel' => 4, // 协议等级,MQTT3.1.1版本为4,5.0版本为5,MQIsdp为3'properties' => [], // MQTT5 中所需要的属性'delay' => 3000, // 重连时的延迟时间 (毫秒)
//            'maxAttempts' => 5, // 最大重连次数。默认-1,表示不限制'maxAttempts' => -1, // 最大重连次数。默认-1,表示不限制'swooleConfig' => ['open_mqtt_protocol' => true,'package_max_length' => 2 * 1024 * 1024]],'host' => RABBITMQ_DEFAULT_HOST,'port' => MQTT_DEFAULT_PORT,'appID' => 'clientMqtt2','appSecret' => 'public','publishUrl' => 'http://' . RABBITMQ_DEFAULT_HOST . ':15672/api/v4/mqtt/publish',],
];

src\console\controllers\EasySwooleController.php

<?phpnamespace console\controllers;use Yii;
use yii\console\Controller;
use yii\helpers\ArrayHelper;
use EasySwoole\EasySwoole\Command\CommandRunner;
use EasySwoole\Command\Caller;/*** Console controller for Easyswoole** @author Ben bi <bennybi@qq.com>*/
class EasySwooleController extends Controller {public $daemon;public $force;public function options($actionID) {return ArrayHelper::merge(parent::options($actionID), ['daemon', 'force',]);}public function optionAliases() {return ArrayHelper::merge(parent::optionAliases(), ['d' => 'daemon','force' => 'force',]);}public function actionServer(...$args) {$argv = $this->getArgv('easy-swoole/server', 'server');
//        Yii::info($argv);$caller = new Caller();$caller->setScript(current($argv));$caller->setCommand(next($argv));$caller->setParams($argv);reset($argv);$ret = CommandRunner::getInstance()->run($caller);if ($ret && !empty($ret->getMsg())) {echo $ret->getMsg() . "\n";}}public function actionProcess(...$args) {$argv = $this->getArgv('easy-swoole/process', 'process');
//        Yii::info($argv);$caller = new Caller();$caller->setScript(current($argv));$caller->setCommand(next($argv));$caller->setParams($argv);reset($argv);$ret = CommandRunner::getInstance()->run($caller);if ($ret && !empty($ret->getMsg())) {echo $ret->getMsg() . "\n";}}public function actionTask(...$args) {$argv = $this->getArgv('easy-swoole/task', 'task');
//        Yii::info($argv);$caller = new Caller();$caller->setScript(current($argv));$caller->setCommand(next($argv));$caller->setParams($argv);reset($argv);$ret = CommandRunner::getInstance()->run($caller);if ($ret && !empty($ret->getMsg())) {echo $ret->getMsg() . "\n";}}protected function getArgv($script, $action) {$argv = $_SERVER['argv'];if (is_array($argv) && $argv['0'] = 'yii') {array_shift($argv);}array_shift($argv);array_unshift($argv, $action);array_unshift($argv, $script);return $argv;}public function getActionHelp($action) {return <<<HELP_START
\e[33m启动操作:\e[0m
\e[31m  php yii easy-swoole/server start [args]\e[0m
\e[33m简介:\e[0m
\e[36m  执行本命令可以启动框架 可选的操作参数如下\e[0m
\e[33m参数:\e[0m
\e[32m  d \e[0m                   以守护模式启动
\e[32m  produce \e[0m             以生产环境启动
\e[33m\e[0m
\e[33m停止操作:\e[0m
\e[31m  php yii easy-swoole/server stop\e[0m
\e[33m\e[0m
\e[33m重启task进程操作:\e[0m
\e[31m  php yii easy-swoole/server reload\e[0m
\e[33m\e[0m
\e[33m重启task + worker进程:\e[0m
\e[31m  php yii easy-swoole/server reload all\e[0m
\e[33m\e[0m
\e[33m进入控制台:\e[0m
\e[31m  php yii easy-swoole/server console\e[0m
HELP_START;}}

daemon/EasSwooleEvent.php 例子

<?phpnamespace EasySwoole\EasySwoole;use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;
use EasySwoole\Component\Process\Config;
use EasySwoole\ORM\Db\Connection;
use EasySwoole\ORM\DbManager;
use EasySwoole\Component\Di;
use EasySwoole\Component\Process\Manager;/*** @author Ben bi <bennybi@qq.com>*/
class EasySwooleEvent implements Event {public static function initialize() {date_default_timezone_set('Asia/Shanghai');}public static function mainServerCreate(EventRegister $register) {/*         * * 设备监控进程mqtt (实时) - 自建队列实时监控设备状态 ** */$devMonitorConfig = new Config();$devMonitorConfig->setProcessName(PROJECT_CODE . '.DeviceMonitorRealTime'); //设置进程名称$devMonitorConfig->setProcessGroup(PROJECT_CODE); //设置进程组$devMonitorConfig->setArg([]); //传参$devMonitorConfig->setRedirectStdinStdout(false); //是否重定向标准io$devMonitorConfig->setPipeType($devMonitorConfig::PIPE_TYPE_SOCK_DGRAM); //设置管道类型$devMonitorConfig->setEnableCoroutine(true); //是否自动开启协程$devMonitorConfig->setMaxExitWaitTime(3); //最大退出等待时间Manager::getInstance()->addProcess(new \daemon\process\rabbitmq\mqtt\IotDeviceMonitorRealTime($devMonitorConfig));/*         * * 设备监控进程mqtt (批量) - 监控IA-TE001-DEVICE-STATUS 持久队列, 防止漏掉信息** */Manager::getInstance()->addProcess(new \daemon\process\rabbitmq\mqtt\IotDeviceMonitorBatch(PROJECT_CODE . '.DeviceMonitorBatch'));/*         * * 传感器Sensors消息进程mqtt (批量) ** */Manager::getInstance()->addProcess(new \daemon\process\rabbitmq\mqtt\IotSensorReportMonitorBatch(PROJECT_CODE . '.SensorReportMonitorBatch'));/*         * * 解析原始数据 (批量) ** */Manager::getInstance()->addProcess(new \daemon\process\rabbitmq\mqtt\IotRawdataParserBatch(PROJECT_CODE . '.RawdataParserBatch'));$register->add($register::onConnect, function (\Swoole\Server $server, int $fd, int $reactor_id) {echo "fd {$fd} connected";});$register->add($register::onReceive, function (\Swoole\Server $server, int $fd, int $reactor_id, string $data) {echo "fd:{$fd} send:{$data}\n";});$register->add($register::onClose, function (\Swoole\Server $server, int $fd, int $reactor_id) {echo "fd {$fd} closed";});}public static function onRequest(Request $request, Response $response): bool {// TODO: Implement onRequest() method.return true;}public static function afterRequest(Request $request, Response $response): void {// TODO: Implement afterAction() method.}}

4.2 守护进程服务命令行

命令 备注
Docker 方式
docker exec ia-php php /var/www/html/te001/yii easy-swoole/server start -d
docker exec ia-php php /var/www/html/te001/yii easy-swoole/server stop
一般方式
php yii easy-swoole/server start -d 守护模式启动
php yii easy-swoole/server start 开发模式启动
php yii easy-swoole/server stop 停止
php yii easy-swoole/server restart 重启

4.3 任务

\daemon\process\rabbitmq\mqtt\IotDeviceMonitorBatch 设备监控进程mqtt (批量) - 监控IA-TE001-DEVICE-STATUS 持久队列

\daemon\process\rabbitmq\mqtt\IotSensorReportMonitorBatch 传感器Sensors消息进程mqtt (批量)

\daemon\process\rabbitmq\mqtt\IotRawdataParserBatch 解析原始数据 (批量)

4.4 服务运行示例

Yii2融合EasySwoole的消息处理服务相关推荐

  1. Yii2 的快速配置 api 服务 yii2-fast-api

    yii2-fast-api yii2-fast-api是一个Yii2框架的扩展,用于配置完善Yii2,以实现api的快速开发. 此扩展默认的场景是APP的后端接口开发,因此偏向于实用主义,并未完全采用 ...

  2. 苏红超:多云融合的电子签章服务平台实践

    7月2日,由中国信息通信研究院主办的"2019可信云大会"在北京召开,法大大高级副总裁兼CTO苏红超受邀出席,分享<多云融合的电子签章服务平台实践>,同时," ...

  3. 口碑饿了么融合一周年 城市生活服务为何变得更"立体"了

    口碑+饿了么所在的本地生活行业,究竟能有多大的想象空间? 一年之前,阿里巴巴组建阿里本地生活服务公司,对本地生活领域的布局还是一个设想.一年之后,打开口碑饿了么,可以逛逛"云"上菜 ...

  4. 三网融合催生第三方数据服务产业

    本文为<证券日报>记者王今对相关业内人士的采访发表在<证券日报>C三版头条文章,采访人士包括汉能投资董事总经理赵小兵,万瑞数据副总裁梅涛,实力媒体北京公司总经理胡颖之,新加坡祥 ...

  5. Proxmox VE 超融合集群不停服务更换硬盘操作实录

    情况描述 四节点组成的proxmox VE超融合集群,连续运行时间超过500天.每个节点除了系统盘而外,由四个单独的2.4T 10000转sas盘做ceph osd. 监控发现,其中一个节点的一块硬盘 ...

  6. 华云数据吴迦德:构建多云融合的行业场景服务

    2018年3月21-22日,由中国信息通信研究院主办.中国通信标准化协会支持的"OSCAR云计算开源产业大会"在国家会议中心举行. 混合云论坛作为"OSCAR云计算开源产 ...

  7. yii2 请求外部api_微服务架构之「 API网关 」

    作者:奎哥来自公众号:不止思考 在微服务架构的系列文章中,前面已经通过文章<架构设计之「服务注册 」>介绍过了服务注册的原理和应用,今天这篇文章我们来聊一聊「 API网关 」. 「 API ...

  8. SOA推动电信服务走向融合应用

    从2005年开始,SOA市场开始出现增长势头,2006年是其快速发展的一年.Gartner认为SOA将成为创建和交付软件的主导框架,同时预测到2010年时,应用软件收入增长的80%将来自基于SOA的方 ...

  9. 医疗信息安全刻不容缓,浪擎发布全融合医疗灾备云服务

    随着"互联网+"的进一步落地,科技发展促进企业IT数字化转型,互联网的红利给企业和人们带来巨大的便捷,而作为与老百姓生活息息相关的健康医疗行业,医院信息化建设也是互联网时代下医院创 ...

最新文章

  1. CentOS 7安装gitlab服务器
  2. nginx 负载均衡配置_Nginx负载均衡NFS配置
  3. linux ubuntu下怎样将pdf格式文件转换为doc格式文件,Ubuntu环境下把word文档转成pdf,把pdf文件转成jpg...
  4. 糍粑大叔的独游之旅-开篇语
  5. Linux C :Linux 下第一个C程序
  6. node搭建服务器,写接口,调接口,跨域
  7. 如何手工抓取dump文件及分析
  8. python为什么不会溢出_深入分析python中整型不会溢出问题
  9. BZOJ 4143: [AMPPZ2014]The Lawyer( sort )
  10. SAP 43亿美元收购Ariba 拓展云计算市场
  11. 使用Zabbix进行风险管理
  12. BCDboot.exe
  13. 免费分享佳能ir c3320 c3330 c3325彩色复印机中文维修手册
  14. Revit 和 ArchiCAD 在软件设计理念方面的对比
  15. Vue搭脚手架及创建项目
  16. 局域网组网 | 路由器常用命令
  17. [C语言] PTA 7-55 查询水果价格
  18. 第14章-cpp代码重用(其他继承模板)
  19. “枪枪爆头”!用Python写个了使命召唤外挂
  20. window系统命令行切换当前目录

热门文章

  1. 电脑桌面显示悬浮文字_工作中记录每天做事的软件选择什么电脑桌面便签软件?...
  2. VMware:启动Centos7报Entering emergency mode. Exit the shell to continue
  3. ISE联合Modelsim仿真失败的解决办法
  4. windows访问Github解决方案
  5. powerjob的worker启动,研究完了这块代码之后我发现了,代码就是现实中我们码农的真实写照
  6. Web3 更应关注类型,而非去中心化程度/链游数字藏品开发
  7. 前端需要了解的泳道概念
  8. 【Unity3D】碰撞体组件Collider
  9. css 左箭头右箭头
  10. strtoul函数的用法