phpバックエンドsocketサービス長リンク、マルチ同時開発メモ

2910 ワード


            //       
            if($this->_maxFork >0  && $this->_children > $this->_maxFork)
            {
                Yii::log("_children > ".$this->_maxFork,CLogger::LEVEL_WARNING,__METHOD__);
                $this->handler(SIGCHLD);
//                 usleep(200);
                continue;
            }


    /**
     *     
     * @param object socket $clientt
     * @return boolean
     */
    public function handler($signo) {
        
        Yii::log("handler {$signo} ",CLogger::LEVEL_INFO, __METHOD__);
        
        switch(intval($signo)) {
            case SIGCLD:
            case SIGCHLD:
                
                Yii::log("SIGCHLD sub proccess   ",CLogger::LEVEL_TRACE, __METHOD__);
                //    
                //declare = 1, that means one signal may be correspond multi-process die 
                while( ($pid = pcntl_wait($status, WNOHANG|WUNTRACED)) > 0 ) {
                    if (FALSE === pcntl_wifexited($status)) {
                        Yii::log("sub proccess {$pid} exited unormally with code {$status}",CLogger::LEVEL_WARNING, __METHOD__);
                    } else {
                        Yii::log("sub proccess {$pid} exited normally",CLogger::LEVEL_INFO, __METHOD__);
                    }
                    $this->_children--;
                }
                break;
            case SIGINT:
            case SIGQUIT:
            case SIGHUP:
                //    
               $this->_cleanup();
                exit(0);
                break;
            default:
                break;
        }
    }

【マルチプロセス方式注意点】
変数共有の問題
プロセスであるため、メインプロセスのコピーとして理解でき、実行は呼び出しpcntl_から行われる.fork()後、各プライマリ、サブプロセスは後で実行され、サブプロセスがネストされないようにします.一般的に、サブプロセスが実行された後、exit(0)で終了します.サブプロセス実行中にクラッシュが発生してもメインプロセスには影響しません.また、メインプロセスと変数を共有することはできません.
信号とselectの競合問題
pcntl_Signal登録信号はstream_とselectに競合がある
PHP Error[2]: stream_select():unable to select[4]:中断されたシステム呼び出し(max_fd=10)
現在、解決策は見つかりません.pcntlを使用していません.signalは監視を行う.
プロセス回収
サブプロセスがexitで終了するとゾンビプロセスになり、pcntl_を通過する必要があります.waitで回収します.
centosテストで最大のプロセス上限は3.2万で、サブプロセスの総数を設定することで、設定値より大きくpcntl_を呼び出すことができます.回収する
ソケット読み書き注意
マルチプロセスの場合、同じsocketハンドルに対して複数のプロセスが同時に読み込まれるという問題が発生します.
解決策は,リード操作がメインプロセスにあり,すべてのデータを読み出した後,サブプロセスに投げて実行する.
ファイル操作の注意
filesize関数は、マルチプロセスの場合、ファイルサイズが取得できないか、取得されないかの問題が発生します.
ここではlinuxを直接呼び出すシステム関数を用いて解決する.
        $file_size  = @filesize($logFile);
//同時実行でファイルサイズが取れない問題の解決
        if(0 == $file_size  ||$this->_prevFileSize == $file_size  )
        {            
            $file_size  = @exec('/usr/bin/stat -c %s '. escapeshellarg($logFile));
            clearstatcache();           
        }
圧力テスト後の1000の同時実行は、350秒間の要求に達することができる.また最適化できるはずです.