鍍金池/ 問答/PHP  網(wǎng)絡(luò)安全/ workerman onWorkerStart初始化redis連接疑問

workerman onWorkerStart初始化redis連接疑問

這使用workerman的gateway框架的時候遇到的疑問
Events.php

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于檢測業(yè)務(wù)代碼死循環(huán)或者長時間阻塞等問題
 * 如果發(fā)現(xiàn)業(yè)務(wù)卡死,可以將下面declare打開(去掉//注釋),并執(zhí)行php start.php reload
 * 然后觀察一段時間workerman.log看是否有process_timeout異常
 */
//declare(ticks=1);

use \GatewayWorker\Lib\Gateway;
use Workerman\Lib\Timer;
use \Server\Common;
use \Server\Cmd;
/**
 * 主邏輯
 * 主要是處理 onConnect onMessage onClose 三個方法
 * onConnect 和 onClose 如果不需要可以不用實(shí)現(xiàn)并刪除
 */
class Events
{
    public static $redisCon = null ;
    /**
     * 當(dāng)客戶端連接時觸發(fā)
     * 如果業(yè)務(wù)不需此回調(diào)可以刪除onConnect
     * 
     * @param int $client_id 連接id
     */
    public static function onConnect($client_id  ) {
        
    }
   /**
    * 當(dāng)客戶端發(fā)來消息時觸發(fā)
    * @param int $client_id 連接id
    * @param mixed $message 具體消息
    */
   public static function onMessage($client_id, $message) {
      
   }
   public static function onWorkerStart($businessWorker){
        self::initRedis();
   }
   /**
    * 當(dāng)用戶斷開連接時觸發(fā)
    * @param int $client_id 連接id
    */
   public static function onClose($client_id) {
        echo "client_id is $client_id is close \n";
   }
   //redis的初始化
   public static function  initRedis(){
        $redisConfig = require_once __DIR__ . "/Server/Config/Redis.config.php";
        self::$redisCon = Server\Library\RedisDB::getInstance( $redisConfig , 0  );
   }
}

RedisDB.php

<?php
namespace Server\Library ;
class RedisDB
{
    static $_instance; //存儲對象
    public $handler;
    private $config = null ;
    public function __construct($redisConfig , $dbindex = 0){
        if (!extension_loaded('redis')) {
            throw new Exception("REDIS NOT  SUPPORT", 1);
        }
        $this->handler = new \Redis();
        //從配置讀取
        $this->handler->pconnect($redisConfig['hostname'], $redisConfig['port']);
        $this->handler->auth($redisConfig['auth']);
    }

    public static function getInstance($redisConfig , $index = 0)
    {
        if (!isset(self::$_instance[$index]) or FALSE == (self::$_instance[$index] instanceof self)) {
            self::$_instance[$index] = new self($redisConfig , $index);
        }
        return self::$_instance[$index];
    }  
}

start_businessworker.php
我開啟了

$worker->count = 8;

疑問:

這初始化redis的連接的時候,我發(fā)現(xiàn)會new redis連接8次
id=1017 addr=192.168.2.188:56012 fd=9 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1018 addr=192.168.2.188:56013 fd=10 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1019 addr=192.168.2.188:56016 fd=11 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1020 addr=192.168.2.188:56025 fd=12 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1021 addr=192.168.2.188:56024 fd=13 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1022 addr=192.168.2.188:56028 fd=14 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1023 addr=192.168.2.188:56038 fd=15 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth
id=1024 addr=192.168.2.188:56039 fd=16 name= age=659 idle=659 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=auth

但是我上面 初始化連接之后只是賦給一個類的靜態(tài)變量。這樣的話 那豈不是只有1個連接????
難道根據(jù)worker的id進(jìn)行嗎?
請指教


上面我redis連接使用了單例的模式!?。?!

回答
編輯回答
枕頭人

官方描述

注意:onWorkerStart是在子進(jìn)程啟動時運(yùn)行的,如果開啟了多個子進(jìn)程($worker->count > 1),每個子進(jìn)程運(yùn)行一次,則總共會運(yùn)行$worker->count次。

因?yàn)槭?進(jìn)程,各子進(jìn)程內(nèi)資源不共享。所以單例模式在此無效;解決方法:在父進(jìn)程執(zhí)行,傳入子進(jìn)程即可。

2018年5月22日 06:52
編輯回答
真難過

這個workerman與thinkPHP的實(shí)戰(zhàn)項目視頻不錯,利用websocket協(xié)議實(shí)現(xiàn)了長連接,來做即時通訊,在線客服。地址 http://study.163.com/course/i...

2018年1月18日 08:05