Yii2融合EasySwoole的消息处理服务
目录
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的消息处理服务相关推荐
- Yii2 的快速配置 api 服务 yii2-fast-api
yii2-fast-api yii2-fast-api是一个Yii2框架的扩展,用于配置完善Yii2,以实现api的快速开发. 此扩展默认的场景是APP的后端接口开发,因此偏向于实用主义,并未完全采用 ...
- 苏红超:多云融合的电子签章服务平台实践
7月2日,由中国信息通信研究院主办的"2019可信云大会"在北京召开,法大大高级副总裁兼CTO苏红超受邀出席,分享<多云融合的电子签章服务平台实践>,同时," ...
- 口碑饿了么融合一周年 城市生活服务为何变得更"立体"了
口碑+饿了么所在的本地生活行业,究竟能有多大的想象空间? 一年之前,阿里巴巴组建阿里本地生活服务公司,对本地生活领域的布局还是一个设想.一年之后,打开口碑饿了么,可以逛逛"云"上菜 ...
- 三网融合催生第三方数据服务产业
本文为<证券日报>记者王今对相关业内人士的采访发表在<证券日报>C三版头条文章,采访人士包括汉能投资董事总经理赵小兵,万瑞数据副总裁梅涛,实力媒体北京公司总经理胡颖之,新加坡祥 ...
- Proxmox VE 超融合集群不停服务更换硬盘操作实录
情况描述 四节点组成的proxmox VE超融合集群,连续运行时间超过500天.每个节点除了系统盘而外,由四个单独的2.4T 10000转sas盘做ceph osd. 监控发现,其中一个节点的一块硬盘 ...
- 华云数据吴迦德:构建多云融合的行业场景服务
2018年3月21-22日,由中国信息通信研究院主办.中国通信标准化协会支持的"OSCAR云计算开源产业大会"在国家会议中心举行. 混合云论坛作为"OSCAR云计算开源产 ...
- yii2 请求外部api_微服务架构之「 API网关 」
作者:奎哥来自公众号:不止思考 在微服务架构的系列文章中,前面已经通过文章<架构设计之「服务注册 」>介绍过了服务注册的原理和应用,今天这篇文章我们来聊一聊「 API网关 」. 「 API ...
- SOA推动电信服务走向融合应用
从2005年开始,SOA市场开始出现增长势头,2006年是其快速发展的一年.Gartner认为SOA将成为创建和交付软件的主导框架,同时预测到2010年时,应用软件收入增长的80%将来自基于SOA的方 ...
- 医疗信息安全刻不容缓,浪擎发布全融合医疗灾备云服务
随着"互联网+"的进一步落地,科技发展促进企业IT数字化转型,互联网的红利给企业和人们带来巨大的便捷,而作为与老百姓生活息息相关的健康医疗行业,医院信息化建设也是互联网时代下医院创 ...
最新文章
- CentOS 7安装gitlab服务器
- nginx 负载均衡配置_Nginx负载均衡NFS配置
- linux ubuntu下怎样将pdf格式文件转换为doc格式文件,Ubuntu环境下把word文档转成pdf,把pdf文件转成jpg...
- 糍粑大叔的独游之旅-开篇语
- Linux C :Linux 下第一个C程序
- node搭建服务器,写接口,调接口,跨域
- 如何手工抓取dump文件及分析
- python为什么不会溢出_深入分析python中整型不会溢出问题
- BZOJ 4143: [AMPPZ2014]The Lawyer( sort )
- SAP 43亿美元收购Ariba 拓展云计算市场
- 使用Zabbix进行风险管理
- BCDboot.exe
- 免费分享佳能ir c3320 c3330 c3325彩色复印机中文维修手册
- Revit 和 ArchiCAD 在软件设计理念方面的对比
- Vue搭脚手架及创建项目
- 局域网组网 | 路由器常用命令
- [C语言] PTA 7-55 查询水果价格
- 第14章-cpp代码重用(其他继承模板)
- “枪枪爆头”!用Python写个了使命召唤外挂
- window系统命令行切换当前目录
热门文章
- 电脑桌面显示悬浮文字_工作中记录每天做事的软件选择什么电脑桌面便签软件?...
- VMware:启动Centos7报Entering emergency mode. Exit the shell to continue
- ISE联合Modelsim仿真失败的解决办法
- windows访问Github解决方案
- powerjob的worker启动,研究完了这块代码之后我发现了,代码就是现实中我们码农的真实写照
- Web3 更应关注类型,而非去中心化程度/链游数字藏品开发
- 前端需要了解的泳道概念
- 【Unity3D】碰撞体组件Collider
- css 左箭头右箭头
- strtoul函数的用法