php使⽤swoole的应⽤场景
应⽤场景简介
1. 与硬件设备连接通讯(定位设备)
2. 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,再⼴播给⽤户
场景2 - 只收集定位设备⼊库
说明:需要把所有的定位设备上传的数据⼊库,设备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 Swoole\Server($config['server']['host'], $config['server']['port']); // 连接redis
$this->redis = new Predis\Client($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) {
php初学者项目$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: .
官⽅wiki:
好处
1. 封装了数据库的model类,数据库的ORM接⼝
2. redis的封装,可以实现多实例访问
3. 框架有⼀些常⽤的⽅法,像log 等等(我只⽤到了log)
4. webim 官⽅有demon,可以参考
坏处:
1. ⽂档特别不全,⼀个简单的实现会折腾半天
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论