摘要:单进程读写性能可达万,不同的进程使用不同的管道通信,可以最大化利用多核。但这任务如果是调用程序接口时,由于网络的延迟,增加的任务大于消费的任务时,内存占用会不断的增加,导致服务器的内存被占满。
应用场景简介
与硬件设备连接通讯(定位设备)
IM系统(用于直播页面的聊天通讯)
场景1 - 实时收集定位数据实时输出(例 滴滴司机行驶轨迹)说明:
需要将所有的定位设备实时的接收,将实时的轨迹记录显示在地图上
注意点:
第一点:
web1服务器 连接的用户1,2,3,web1广播信息时只能广播用户1,2,3,不能广播web2连接的用户4,5,6,假设场景是聊天,用户1发送一消息,只有web1 服务器的用户能看到,web2的用户全部不能收到
第二点:消息的频率控制,例:100个设备,100个用户, 100个设备每秒上传一条数据,需要实时广播给每个用户,就是每秒要100*100 = 1W次,所以可以汇总每秒数据广播给所有用户等等方法
数据传输的流程图:
不包含业务逻辑,将web1,web2,接收的消息汇总然后再广播给web1,web2,再广播给用户
说明:需要把所有的定位设备上传的数据入库,设备7个,每秒一条数据,个人使用swoole 的task 函数(投递一个异步的任务到 task_worker池中,此函数是非阻塞的, worker进程数同样可以配置) 后调用接口方式入库
服务器内存报警问题
原因: 在于swoole_server->task 函数
官方介绍task底层使用Unix Socket管道通信,是全内存的,没有IO消耗。单进程读写性能可达100万/s,不同的进程使用不同的管道通信,可以最大化利用多核。
但这任务如果是调用程序接口时,由于网络的延迟,增加的任务大于消费的任务时,内存占用会不断的增加,导致服务器的内存被占满。
解决方法:消息针对入任务的频率控制,可以根据自己的业务场景定义这个时间与是否可延迟等情况,汇总1秒内的所有数据再调用程序接口(汇总时个人使用redis),最好能直接入库,不必调用接口
简单代码片段,不全(供初学者了解,官方网站demo相似)
function __construct($config) { $this->config = $config; $this->serv = new SwooleServer($config["server"]["host"], $config["server"]["port"]); // 连接redis $this->redis = new PredisClient($config["redis"]); $this->storage = new Storage($this->config); $this->serv->set([ "worker_num" => $this->config["server"]["workerNum"], //工作进程数量 "daemonize" => $this->config["server"]["daemonize"], //是否作为守护进程 "task_worker_num" => $this->config["server"]["taskWorkerNum"], ]); $this->serv->on("connect", function ($serv, $fd){ $this->onConnect($fd, $serv); }); $this->serv->on("receive", function ($serv, $fd, $from_id, $data) { $this->onReceive($fd, $serv, $data); }); $this->serv->on("Close", function($server, $fd) { $this->onClose($fd, $server); }); $this->serv->on("Task", function($server, $task_id, $from_id, $data) { $this->onTask($server, $task_id, $from_id, $data); }); $this->serv->on("Finish", function($server, $task_id, $data) { $this->onFinish($server, $task_id, $data); }); $this->serv->start(); } public function onTask($serv, $task_id, $from_id, $data){ // insert 方法是通过接口入库 $this->storage->insert($data); } public function onReceive($fd, $serv, $data) { $this->storage->writeLog("message:".$data); $data = $this->formatData($data, $fd); $serv->task($data); } public function onClose($fd, $serv) { // writeLog 方法是写入log $this->storage->writeLog("close fd:".$fd); } public function onFinish($serv, $task_id, $data) { return ""; }场景-IM系统
参考官方github: webim系统.
官方wiki: swoole 框架wiki
好处
封装了数据库的model类,数据库的ORM接口
redis的封装,可以实现多实例访问
框架有一些常用的方法,像log 等等(我只用到了log)
webim 官方有demon,可以参考
坏处:
文档特别不全,一个简单的实现会折腾半天
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/26116.html
摘要:是一个基于扩展实现的轻量级高性能的常驻内存型的和应用服务框架高度封装了,,服务器,以及基于实现可扩展的服务,同时支持包方式安装部署项目。基于实用,抽象事件处理类,实现与底层的回调的解耦,支持同步异步调用,内置等常用组件等。 swoolefy swoolefy是一个基于swoole扩展实现的轻量级高性能的常驻内存型的API和Web应用服务框架,高度封装了http,websocket,ud...
摘要:在禁止场景中使用协程会出现各种莫名其妙的问题发生。限制了协程的应用范围。新版本基于汇编代码实现了全新的协程内核。实现了对所有语法的支持。稳定性和健壮性均已达到工业级的水准。完全可用于大型项目的生产环境中。 Swoole虽然在2016年就支持了协程特性,但由于底层是基于setjmp/longjmp实现的stackless方案。因此在某些场景下,如call_user_func、array_...
摘要:在中的应用官网源码解读号外号外欢迎大家我们开发组定了一个就线下聚一次的小目标上一篇源码解读反响还不错不少同学推荐再加一篇讲解一下中使用到的功能帮助大家开启的实战之旅服务器开发涉及到的相关技术领域的知识非常多不日积月累打好基础是很难真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的应用 swoft 官网: https://www.sw...
摘要:异步操作废话不说直接进入正题应用场景业务逻辑中经常会出现发送信息发送邮件记录日志等等这个时候用异步再好不过了用户直接的体验就是使用的贼流畅使用技术这个不仅仅支持了其他语言也支持有的扩展用起来更方便感觉上异步队列不同点有个队列专门用来存储发送 PHP异步操作 废话不说直接进入正题: 应用场景: 业务逻辑中经常会出现发送信息,发送邮件,记录日志等等,这个时候用异步再好不过...
摘要:抢占式调度我们在今年年初就计划实现的抢占式调度,以满足实现有些场景下的不均衡调度带来的问题。考虑开线程,负责检查当前执行协程执行时间。达到我们的第二个协程主动抢占第一个协程的效果。 前言 Swoole内核团队开设的专栏,会逐渐投入精力写文章介绍Swoole的开发历程,实现原理,应用实践等,大家可以更好的交流,共同学习,建设PHP生态。 协程调度 去年Swoole推出了4.0版本后,完整...
阅读 3561·2021-11-22 09:34
阅读 3168·2021-11-15 11:38
阅读 2863·2021-10-27 14:16
阅读 1192·2021-10-18 13:35
阅读 2396·2021-09-30 09:48
阅读 3354·2021-09-29 09:34
阅读 1522·2019-08-30 15:54
阅读 1787·2019-08-26 11:57