zoukankan      html  css  js  c++  java
  • 三 分析easyswoole源码(启动服务&TableManager,略提及Cache工具的原理)

    前文连接,讲了es是如何启动swoole服务的。

    里面有一个工具类TableManager。这个类为了处理进程间数据共享。是对swoole_table的一层封装
    swoole_table一个基于共享内存和锁实现的超高性能,并发数据结构。用于解决多进程/多线程数据共享和同步加锁问题。

    TableManager主要做了下面几件事
    add方法
    如果$list数组中有这个表名($name是一个表名或者叫做集合名),就初始化swoole_table,然后配置的字段类型数组进行创建

    if(!isset($this->list[$name])){
        $table = new Table($size);
        foreach ($columns as $column => $item){
            $table->column($column,$item['type'],$item['size']);
        }
        $table->create();
        $this->list[$name] = $table;
    }

    get方法
    直接返回swoole_table的实例。

    使用的地方有很多
    前文提到的在系统设置Cache组件 Cache::getInstance()的时候

    构造方法做了如下事情

    $num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM"));//Config默认配置是1,如果配置为小于等于0则不开启Cache
    if($num <= 0){
       return;
    }
    $this->cliTemp = new SplArray();
    //若是在主服务创建,而非单元测试调用
    if(ServerManager::getInstance()->getServer()){
        //创建table用于数据传递
        TableManager::getInstance()->add(self::EXCHANGE_TABLE_NAME,[
            'data'=>[
                'type'=>Table::TYPE_STRING,
                'size'=>10*1024
            ],
            'microTime'=>[
                'type'=>Table::TYPE_STRING,
                'size'=>15
            ]
        ],2048);
        //创建了一个__Cache的swoole_table表,字段为 data String 10240,microTime String 15的表
        $this->processNum = $num;
        for ($i=0;$i < $num;$i++){
            ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class);
        }
    }

    ProcessManager也是一个很重要的概念。其实就是一个管理任务映射的工具。

    这里可以看到ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class)

    其实这里是通过ProcessManager,让swoole服务添加了一个进程。swoole的addProcess方法,文档链接https://wiki.swoole.com/wiki/page/390.html

    提前略带讲解一下Cache的set方法加深概念

    //讲解一下Cache的set方法加深概念
    if(!ServerManager::getInstance()->isStart()){//兼容测试模式。也就是不开启服务的情景下直接是clitemp中取缓存数据
        $this->cliTemp->set($key,$data);
    }
    if(ServerManager::getInstance()->getServer()){
        $num = $this->keyToProcessNum($key);//这里是通过key然后hash到应该投放的Cache进程中去。
        $msg = new Msg();
        $msg->setCommand('set');
        $msg->setArg('key',$key);
        $msg->setData($data);
        //下面一句话还是挺复杂的,根据key名hash到ProcessManager对应的映射,然后获取到swoole_process的实例,以swoole的write函数向管道内写入数据。
        ProcessManager::getInstance()->getProcessByName($this->generateProcessName($num))->getProcess()->write(swoole_serialize::pack($msg));
        //在写完数据后,在CacheProcess的onReceive方法中可以看到对应setCommand的操作细节。其实数据都被写到了一个Arr数组中。下篇接着讲一下Cache的实现细节。这节还是主要讲TableManager和它的相关作用.
    }
  • 相关阅读:
    Python:如何将文件映射到内存
    关于系统中:/dev/mem
    Python:如何设置文件的缓冲
    Python:如何处理二进制文件
    Python:struct模块的pack、unpack
    Python:如何读写文本文件
    《鸟哥的Linux私房菜》读书笔记3
    《鸟哥的Linux私房菜》读书笔记2
    《鸟哥的Linux私房菜》读书笔记1
    raspberry是个什么玩意
  • 原文地址:https://www.cnblogs.com/gavinjunftd/p/9435702.html
Copyright © 2011-2022 走看看