php使用swoole的应用场景

应用场景简介

  1. 与硬件设备链接通信(定位设备)git

  2. IM系统(用于直播页面的聊天通信)github

场景1 - 实时收集定位数据实时输出(例 滴滴司机行驶轨迹)

说明:
须要将全部的定位设备实时的接收,将实时的轨迹记录显示在地图上web

注意点:
第一点:
web1服务器 链接的用户1,2,3,web1广播信息时只能广播用户1,2,3,不能广播web2链接的用户4,5,6,假设场景是聊天,用户1发送一消息,只有web1 服务器的用户能看到,web2的用户所有不能收到redis

图片描述

第二点:消息的频率控制,例:100个设备,100个用户, 100个设备每秒上传一条数据,须要实时广播给每一个用户,就是每秒要100*100 = 1W次,因此能够汇总每秒数据广播给全部用户等等方法数据库

数据传输的流程图:
不包含业务逻辑,将web1,web2,接收的消息汇总而后再广播给web1,web2,再广播给用户服务器

图片描述

场景2 - 只收集定位设备入库

说明:须要把全部的定位设备上传的数据入库,设备7个,每秒一条数据,我的使用swoole 的task 函数(投递一个异步的任务到 task_worker池中,此函数是非阻塞的, worker进程数一样能够配置) 后调用接口方式入库swoole

服务器内存报警问题网络

缘由: 在于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) {
        $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

好处

  1. 封装了数据库的model类,数据库的ORM接口

  2. redis的封装,能够实现多实例访问

  3. 框架有一些经常使用的方法,像log 等等(我只用到了log)

  4. webim 官方有demon,能够参考

坏处:

  1. 文档特别不全,一个简单的实现会折腾半天

相关文章
相关标签/搜索