찾다
php教程php手册php 后端socket服务长链接,多并发开发备忘

php 后端socket服务长链接,多并发开发备忘

Jun 13, 2016 am 10:56 AM
phpsocket상한보장하다후방경쟁 상대개발하다제공하다프로세스링크


[php]
       //保证子进程上限  
        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; 
    } 

            //保证子进程上限
            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_wait 来进行回收


socket读写注意
多进程情况下,会出现对同个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每秒的请求。应该还可优化。

 

 

 

 

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.