如何控制指定哪个进程来接收客户端连接?

dignfei
use Workerman\Worker;
require __DIR__.'/../vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:2120');
$worker->count = 1;
$worker->onWorkerStart = function($worker)
{
    // 读取数据,需要5秒。
}
$worker->onMessage = function($connection, $data)
{
    global $worker;
    global $ppp ;
    $pid = pcntl_fork();
    if  ($pid==0) { //父进程会得到子进程pid号,子进程$pid是0
        $ppp = $pid;
        return;
    } else {
        $ppp = $pid;
    }
};
// 运行worker
Worker::runAll();

需求:我需要把大量数据读取到内存,供客户端查询,需要做到0.2s内响应。数据同时在不断更新,每5秒又要重新去读取数据。
请问这个可以怎么实现?
我的不成熟想法:在onMessage中fork了一个进程,总共2个进程,
进程1个提供服务,进程2去读取最新数据
5秒后,进程1去读取最新数据,进程2提供服务,
又5秒后,进程1提供服务,进程2去读取最新数据
问题是如何指定一个进程来处理客户端请求?

2800 3 0
3个回答

th

为什么不设置$worker->count = 进程数???

  • dignfei 2020-03-14

    把数据读取到PHP数组,会占用6000M内存,用fork可以2个进程共用这部分内存

six

感觉不用fork进程,开2个进程弄个锁就搞定了。

use Workerman\Worker;
require __DIR__.'/../vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:2120');
// 开启2个进程
$worker->count = 2;
$data = [];
$worker->onWorkerStart = function($worker)
{
     // 定时每5秒去load以下数据
     Workerman\Lib\Timer::add(5, function(){
         // 获取锁,避免2个进程同时在load数据到内存,没有进程提供查询服务
         $fp = fopen(__FILE__, 'r');
         if (!flock($fp, LOCK_EX | LOCK_NB )) {
             return;
         }
         global $data;
         $data = your_load_function();
         flock($fp, LOCK_UN);
     });
}
$worker->onMessage = function($connection, $msg)
{
    global $data;
    $key = $_GET['key'];
    $connecion->close(isset($data[$key]) ? $data[$key] : '');
};
// 运行worker
Worker::runAll();
  • dignfei 2020-03-14

    把数据读取到PHP数组,会占用6000M内存,用fork可以2个进程共用这部分内存。开2个进程,就要占用2份内存

  • dignfei 2020-03-14

    进程A读取数据,然后fork出进程b1去提供查询服务。然后进程A继续读取新数据,然后fork出进程b2去提供查询服务,然后把b1进程关闭。这样比较好有2个优点:1.只需要一份内存 2.进程A每次只需要读取增量的变化的数据

  • dignfei 2020-03-18

    有么有别的好的解决办法??

  • six 2020-03-18

    加点硬件嘛,加个1G内存很便宜。你想这么多天,人工成本早超过内存了

dignfei

哪位大神能解答一下?????有什么好的解决办法??

  • 暂无评论
年代过于久远,无法发表回答
×
🔝