概述
已经Swoole系列的第二篇知识点了,前一篇主要的针对处理的是方案设计,这一篇主要是代码实现的内容,主要介绍高性能的原因已经实现,编程框架使用EasySwoole。
Swoole 与 EasySwoole
Swoole属于php中的一个超级扩展,它会接管PHP的进程,管理和分配worker,但他依赖 PHP-Cli模式。Swoole和Yaf有相似的地方,它们都是以守护进程的模式、常驻内存的方式达到提高处理性能。
【资料图】
Swoole内置了TCP、UDP、WebSocket、协程、异步、Redis/Mysql链接池等高效开发手段和方法,当然对于新模式也有新的挑战,比如swoole不能使用die,会致使worker滑落,协程使用后要注意使用回调的过程,如果对php的基础知识不了解的同学,可以翻看我之前的php博客里的总结,这里就不过多叙述了。
EasySwoole是一款非常简单上手易操作的Swoole框架,上线2年多以来经得住生产环境的考验,官网文档写的也很详细,还有专门解答的QQ群,大佬们会解答很多问题。
安装EasySwoole框架
之前我使用composer进行安装的(composer是php中管理依赖包的工具,和node里面的npm,python的pip 一样),现在都使用docker镜像直接操作了。
docker pull easyswoole/easyswoole3docker run -ti -p 9501:9501 -p 80:80 --name easyswoole easyswoole/easyswoole3
项目目录结构:
.├── App│ ├── Conf│ ├── Crontab│ ├── HttpController│ │ ├── Api│ │ └── Router.php│ ├── Log│ │ └── LogHandel.php│ ├── Models│ │ ├── ImChatModel.php│ │ ├── ImModel.php│ │ └── PushMsgModel.php│ ├── Parser│ │ └── WebSocketParser.php│ ├── Server│ │ ├── ChangPeiServer│ │ ├── MysqlServer│ │ ├── RedisServer│ │ ├── Server.php│ │ └── WebSocketServer│ ├── Utility│ │ ├── Http│ │ ├── Mall│ │ └── Ws│ ├── WebSocketController│ │ ├── Base.php│ │ ├── Error│ │ ├── V1│ ├── WebSocketEvent.php│ └── WebSocketRoute│ └── ForwardRoute.php├── EasySwooleEvent.php├── Log│ └── swoole.log
注册服务 与启动加载
1.在EasySwooleEvent.php文件中加载初始化需要的Mysql、redis配置文件,所有需要的服务都需要在启动文件中进行注册,才能使用。
public static function loadConf(){ $ConfPath = EASYSWOOLE_ROOT . "/App/Conf/"; $Conf = Config::getInstance(); $files = File::scanDirectory($ConfPath); if (!is_array($files["files"])) { return; } foreach ($files["files"] as $file) { $data = require_once $file; $Conf->setConf(strtolower(basename($file, ".php")), (array)$data); }}
2.注册Mysql连接池,Mysql连接池主要设置参数,
[ "host" => "59.110.162.133", "port" => "3306", "database" => "swoole_msg", //cpwxw2_db_v2 "username" => "work", "password" => "cp2018csq123456", "timeout" => 300, "charset" => "utf8mb4" ], //Mysql连接池配置 "conn_pool" => [ "timeOut" => "3.0", //设置获取连接池对象超时时间 "checkOut" => 30 * 1000, //设置检测连接存活执行回收和创建的周期 "maxidleTime" => 15, //连接池对象最大闲置时间(秒) "maxObjectNumber" => 100, //设置最大连接池存在连接对象数量 "minObjectNumber" => 5, //设置最小连接池存在连接对象数量 "autoPing" => 5, //设置自动ping客户端链接的间隔 ],];
3.注册redis链接池
use \EasySwoole\Redis\Config\RedisConfig;use \EasySwoole\RedisPool\RedisPool;$redisConf = GlobalConfig::getInstance()->getConf("redis");RedisPool::getInstance()->register(new RedisConfig($redisConf),"redis");
4.注册自定义log
use \EasySwoole\EasySwoole\Logger;Logger::getInstance(new \App\Log\LogHandel());
5.我的项目里还使用了crontab模块
use Swoole\Coroutine\Scheduler;use EasySwoole\EasySwoole\Crontab\Crontab;//用户通知队列Crontab::getInstance()->addTask(\App\Crontab\PushUserNoticeMsg::class);
6.添加热启动
Swoole的服务属于常驻内存加载类型的服务,所以每次修改代码后都需要重启服务,所以为了方便,添加了热加载目录,热加载原理就是当检测到指定目录有代码更新时,用传递信号的方式进行,指挥进程进行重新加载。
$hotReloadOptions = new \EasySwoole\HotReload\HotReloadOptions;$hotReload = new \EasySwoole\HotReload\HotReload($hotReloadOptions);$hotReloadOptions->setMonitorFolder([EASYSWOOLE_ROOT . "/App"]);$server = ServerManager::getInstance()->getSwooleServer();$hotReload->attachToServer($server);
7.启动/停止服务,参数说明
-mode 说明启动服务类型
-d 以守护进程的方式
php easyswoole server start -mode=websocket -dphp easyswoole server stop
异步和 DB(Redis/Mysql)使用
1.高性能的异步操作
如果是不依赖于结果的计算,异步操作提高性能的有效手段之一,异步操作不需要等待结果,更好的利用CPU和I/O传输。
use EasySwoole\EasySwoole\Task\TaskManager;TaskManager::getInstance()->async(function () use ($tableName,$data) { // todo code ...});
2.Redis/Mysql使用
在高并发情况下,资源浪费的占用时间越短越好,可以提高程序的服务效率。在ORM默认情况下是使用defer方法获取pool内的连接资源,并在协程退出时自动归还,在此情况下,在带来便利的同时,会造成不必要资源的浪费。
我们可以使用invoke方式,让ORM查询结束后马上归还资源,可以提高资源的利用率。
Mysql的使用Demo.
DbManager::getInstance()->invoke(function (ClientInterface $client)use ($where, $tableName, $count) { $pushMsgModel = PushMsgModel::invoke($client); $pushMsgObj = $pushMsgModel->tableName($tableName) ->field(["push_id"]) ->get($where);}, self::MYSQL_CONN_NAME);
Redis的使用Demo.
## invoke方式public function setAuthorFd(int $uid, int $fd){ RedisPool::invoke(function (Redis $redis) use ($fd, $uid) { $sRet = $redis->zAdd(self::PUSH_MSG_AUTHOR_NOTICE_SYSTEM, $uid, $fd); }, self::REDIS_CONN_NAME);}## defer方式$redis = \EasySwoole\RedisPool\RedisPool::defer("redis");$data = $redis->lRange(self::PUSH_MSG_COMMENT_DELAY_LISTS, 0, 1000);
WebSocket服务
1.WebSocket协议是什么
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
在没有WebSocket协议之前,在网页中,实现一个聊天室只能使用ajax 不断轮询,请求服务器是否有数据产生,而这样的实现方法会出现一系列的问题:
如果轮询时间间隔太短,会导致客户端和服务端在一个时间段内不断的进行http tcp的握手/挥手动作和http 请求头,响应头的传输,大量消耗服务器资源,如果用户量大的情况,会造成服务器的繁忙以至于宕机客户端每次只能通过发送http 请求获得服务器是否有数据返回,且数据的及时性无法保证正因为在这种情况下,所以WebSocket出现了,它只需要一次http握手,就可以保持一个长连接,使得服务器可以主动发送消息给客户端,大大减少了轮询机制的消耗。
2.WebSocket协议实现原理
在实现websocket连线过程中,需要通过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为握手 。
在 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket 协议中,为我们实现即时服务带来了两大好处:
Header: 互相沟通的Header是很小的-大概只有 2 BytesServer Push: 服务器的推送,服务器不再被动的接收到浏览器的请求之后才返回数据,而是在有新数据时就主动推送给浏览器。//$fd,指的是系统里的文件描述符fduse EasySwoole\EasySwoole\ServerManager;$server = ServerManager::getInstance()->getSwooleServer();$server->push($fd,json_encode($messageData));//获取当前链接的详细信息$info = $server->getClientInfo($fd);//获取全部websocket中的链接fd//全员在线消息通知$server = ServerManager::getInstance()->getSwooleServer();$start_fd = 0;while(true){ $conn_list = $server->getClientList( $start_fd, $this->limit ); if ($conn_list===false || count($conn_list) === 0 || empty($conn_list)) { break; } $start_fd = end($conn_list); foreach ($conn_list as $fd){ $info = $server->getClientInfo($fd); if ($info && $info["websocket_status"] === WEBSOCKET_STATUS_FRAME) { $server->push($fd, json_encode($this->pushMsg)); } }}
项目里主要使用的功能点已经讲解完毕了,剩下的等有时间再整理。
(责任编辑:黄俊飞)推荐内容
- Swoole - webSocket消息服务系统代码设
- 电脑开机不显示桌面怎么办
- 棉花糖和云朵妈妈1|环球快播
- 苜蓿的拼音是什么_苜蓿怎么读拼音
- 锤娜丽莎_说一说锤娜丽莎的简介_世界独家
- “鸟巢杯”全国青少年冰雪文化艺术创作系
- 法甲-姆巴佩传射迎里程碑梅西建功 巴黎4
- c罗最帅发型_c罗发型
- 环球速递!如何看加密的相册
- 光遇集结季第三个任务怎么完成_光遇集结
- 每日头条!重庆一批隧道建设项目冲刺“开
- 世界播报:综漫走着瞧
- 最大动物基因组图谱——南极磷虾基因组图
- 东京股市小幅下跌
- 既算生计账 也算生态账|天天热点
- 跷跷板 打一个成语_跷跷板打一个成语
- 全球热文:A股股票回购一览:3家公司披露
- 省地质灾害隐患排查专项行动督查组在我市
- 2022年“大国工匠年度人物”揭晓,武汉这
- across from怎么读_across怎么读_热推荐
- 环球微资讯!潍坊学院与山东蓝想环境科技
- 伊拉克总统拉希德会见联合国秘书长古特雷
- 全球时讯:说女生是什么意思_女生外围是
- 【景顺长城基金】景顺长城核心中景一年持
- 今日要闻!03月01日14时内蒙古巴彦淖尔昨
- 三夏是什么意思_三夏指的是什么_报道
- 华创证券:供给刚性叠加需求复苏 全年看
- “中国可能比美国拥有更多选择”
- 天天要闻:元旦贺卡制作手工立体创意_元
- 看热讯:FcγR基因拷贝数和狼疮性肾炎相
- 经济问题公式初三_经济问题公式 每日热议
- 脚手架搭设多少钱一平方 脚手架搭设
- 焦点滚动:月字旁和什么有关的字_月字旁和
- 创造与魔法天空鳐饲料怎么做_创造与魔法
- 全球看热讯:阵风7级!北京继续发布大风
- 全球微头条丨恩比德或强行交易!勇士6换2
- 李治和武则天啥关系?_李治武则天是什么关
- 每日关注!安徽合肥:“快乐健身”空间再
- 日照“财政动力”赋能绿色低碳高质量发展
- ST宝龙
- 法语原版“罗朱”今年有望来沪,原创剧作
- 头条焦点:苦竹叶速溶饮_关于苦竹叶速溶
- 专家预测2月份CPI同比上涨2.0%
- 东莞五中校服_东莞五中|天天关注
- 如何做小生意妙招_如何做小生意
- 每日热讯!与同事相处需要学问,出现这五
- 万和DSZF40-I
- 淘特在产业带设50个线下服务站,围绕888
- 环球观点:济南大学成教学院枣庄教学部必
- 【环球热闻】社保包含哪几种保险_社保保
- 我想找点手工活在家做哪里有_我想找点手
- 每日热闻!天津滨海新区 宁河区划定疫情
- 湖北今年 首场马拉松开跑 世界快资讯
- 使用含药物30和75的两种消毒液
- 上海电影产业发展报告.2017 世界焦点
- 鸡肉市场行情有望好转-全球热资讯
- 前沿热点:井底之蛙怎么解释_井底之蛙怎
- 南极巨虫
- 飘窗的窗帘怎么装好看_世界最资讯
- 楚臣伤江枫下句是什么_楚臣伤江枫下原文
- 环球微资讯!潍坊学院与山东蓝想环境科技
- 伊拉克总统拉希德会见联合国秘书长古特雷
- 全球时讯:说女生是什么意思_女生外围是
- 【景顺长城基金】景顺长城核心中景一年持
- 今日要闻!03月01日14时内蒙古巴彦淖尔昨
- 三夏是什么意思_三夏指的是什么_报道
- 华创证券:供给刚性叠加需求复苏 全年看
- “中国可能比美国拥有更多选择”
- 天天要闻:元旦贺卡制作手工立体创意_元
- 看热讯:FcγR基因拷贝数和狼疮性肾炎相
- 经济问题公式初三_经济问题公式 每日热议
- 脚手架搭设多少钱一平方 脚手架搭设
- 焦点滚动:月字旁和什么有关的字_月字旁和
- 创造与魔法天空鳐饲料怎么做_创造与魔法
- 全球看热讯:阵风7级!北京继续发布大风
- 全球微头条丨恩比德或强行交易!勇士6换2
- 李治和武则天啥关系?_李治武则天是什么关
- 每日关注!安徽合肥:“快乐健身”空间再
- 日照“财政动力”赋能绿色低碳高质量发展
- ST宝龙
- 法语原版“罗朱”今年有望来沪,原创剧作
- 头条焦点:苦竹叶速溶饮_关于苦竹叶速溶
- 专家预测2月份CPI同比上涨2.0%
- 东莞五中校服_东莞五中|天天关注
- 如何做小生意妙招_如何做小生意
- 每日热讯!与同事相处需要学问,出现这五
- 万和DSZF40-I
- 淘特在产业带设50个线下服务站,围绕888
- 环球观点:济南大学成教学院枣庄教学部必
- 【环球热闻】社保包含哪几种保险_社保保
- 我想找点手工活在家做哪里有_我想找点手
- 每日热闻!天津滨海新区 宁河区划定疫情
- 湖北今年 首场马拉松开跑 世界快资讯
- 使用含药物30和75的两种消毒液
- 上海电影产业发展报告.2017 世界焦点
- 鸡肉市场行情有望好转-全球热资讯
- 前沿热点:井底之蛙怎么解释_井底之蛙怎
- 南极巨虫
- 飘窗的窗帘怎么装好看_世界最资讯
- 楚臣伤江枫下句是什么_楚臣伤江枫下原文
- 东商务区
- 每日速讯:如何建造屋顶蟋蟀
- 严锦-热闻
- 2023广东省公务员考试报名人数查询_2020
- 环球快消息!Slater:明日对阵森林狼 维
- 中国减速机网
- 梦比优斯奥特曼新传
- 性格内向但是_我的性格是内向吧|要闻速递
- 天天要闻:1天就能赚3万!揭秘街头的那些
- 中国画大师经典系列丛书:项圣谟 观热点
- 喀旗科协开展2023年科普传播行春季活动
- 关兴张苞不死_关兴张苞怎么死的
- 中山市小榄镇建筑装饰业商会 环球简讯
- 摊牌了,法媒透露梅西要求!大巴黎嗅到不
- 无欲则刚
- 全国“冬两”冠军赛男、女接力角逐 内蒙
- 环球观热点:老鼠嫁女故事一年级_老鼠嫁
- 环球百事通!symbians60v5
- 寞的拼音和组词_寞的拼音和组词
- 哈铁列车员整理车厢发现200万日元 及时