다음 칼럼에서는 workerman 튜토리얼 칼럼에서 워커맨 소스코드 분석의 시작 과정을 소개하겠습니다. 도움이 필요한 친구들!
# 🎜 🎜#workerman
Version: 3.1.8 (linux) 모델: GatewayWorker(Worker 모델과 비교 가능) #🎜 🎜#참고: 설명을 위한 코드의 일부만 게시됩니다. 소스는 파일 이름 형식으로 제공됩니다.
workerman은 처음에 Linux 버전만 개발했습니다. win은 나중에 명령줄 모드 run(cli)을 기반으로 추가되었습니다.
다중 프로세스 모델Worker 프로세스, Master, Gateway 및 Worker, Gateway는 주로 다음 작업에 사용됩니다. IO 이벤트 처리, 클라이언트 연결 상태 저장, 작업자에게 데이터 처리 요청 보내기 및 기타 작업 작업자는 완전한 비즈니스 논리 처리입니다. 전자는 IO 집약적이며 후자는 네트워크를 통해 통신합니다. 주소를 쌍으로 구성하므로 분산 배포에 매우 편리합니다. 업무 처리량이 많은 경우 Worker 서비스만 추가하면 됩니다.
그들은 모니터링, 하위 프로세스 상태 모니터링, 하위 프로세스에 신호 보내기 및 명령 수락을 담당하는 상위 프로세스(마스터)가 있습니다. 그리고 터미널에서 신호를 보냅니다. 상위 프로세스는 전체 시스템이 시작된 후의 진입점이라고 할 수 있습니다.
명령 분석 시작 명령 모드(cli)에서 실행한 이후(fpm과의 차이점에 유의하세요. (후자는 웹 페이지의 요청을 처리합니다.) 시작 스크립트 구문 분석 명령이 있어야 합니다. 예를 들어 버전 3. :$daemon = true인 경우 하위 프로세스를 분기하여 현재 프로세스 그룹을 떠나고 프로세스 그룹 리더를 설정합니다. 등.
두 개의 매우 중요한 매개변수 $argc와 $argc가 있습니다. 전자는 매개변수 수를 나타내고 후자는 sudo php start와 같이 명령의 모든 매개변수를 저장하는 배열입니다. php start - d, $argv는 array([0]=>start.php, [1]=>start, [2]=>-d)이고 $argv는 주로 구문 분석에 사용됩니다.
시작은 주로 다음 단계를 수행합니다:
1. 각 응용 프로그램 아래에 시작 파일을 로드하는 자동 로더 Autoloader가 포함되어 있습니다. _appInitPath 루트 디렉터리
3을 설정하고, 매개변수를 초기화하고 해당 명령을 실행합니다.
다음은 구체적인 구현입니다(workerman/worker.php):
public static function parseCommand() { // 检查运行命令的参数 global $argv; $start_file = $argv[0]; // 命令 $command = trim($argv[1]); // 子命令,目前只支持-d $command2 = isset($argv[2]) ? $argv[2] : ''; // 检查主进程是否在运行 $master_pid = @file_get_contents(self::$pidFile); $master_is_alive = $master_pid && @posix_kill($master_pid, 0); if($master_is_alive) { if($command === 'start') { self::log("Workerman[$start_file] is running"); } } elseif($command !== 'start' && $command !== 'restart') { self::log("Workerman[$start_file] not run"); } // 根据命令做相应处理 switch($command) { // 启动 workerman case 'start': if($command2 === '-d') { Worker::$daemonize = true; } break; // 显示 workerman 运行状态 case 'status': exit(0); // 重启 workerman case 'restart': // 停止 workeran case 'stop': // 想主进程发送SIGINT信号,主进程会向所有子进程发送SIGINT信号 $master_pid && posix_kill($master_pid, SIGINT); // 如果 $timeout 秒后主进程没有退出则展示失败界面 $timeout = 5; $start_time = time(); while(1) { // 检查主进程是否存活 $master_is_alive = $master_pid && posix_kill($master_pid, 0); if($master_is_alive) { // 检查是否超过$timeout时间 if(time() - $start_time >= $timeout) { self::log("Workerman[$start_file] stop fail"); exit; } usleep(10000); continue; } self::log("Workerman[$start_file] stop success"); // 是restart命令 if($command === 'stop') { exit(0); } // -d 说明是以守护进程的方式启动 if($command2 === '-d') { Worker::$daemonize = true; } break; } break; // 平滑重启 workerman case 'reload': exit; } }
walker 코드 주석은 매우 자세하며 다음은 몇 가지 세부 정보입니다.
#🎜🎜 #1. 메인 프로세스가 살아 있는지 확인합니다: 17행의 논리 AND 연산. 메인 프로세스 PID가 존재하면 프로세스에 신호 0을 보냅니다. 실제로는 프로세스가 있는지 감지하기 위한 것입니다. (또는 프로세스 그룹)이 살아 있고 현재 사용자에게 시스템 신호를 보낼 권한이 있는지 여부도 감지합니다. 2. 시스템이 시작된 후 종료 또는 다른 명령을 실행하려면 해당 명령이 다른 프로세스에서 실행됩니다. 프로세스 PID도 모르는 경우 누구에게 신호를 보내야 합니까? 에게? 그래서 메인 프로세스의 PID를 저장해야 하고, 메인 프로세스는 다른 하위 프로세스를 모니터링하는 역할을 담당하므로 작업을 계속하기 위한 입구입니다. Worker::runAll()PHP 소켓 프로그래밍은 실제로 C와 유사하며 후자는 소켓이 다시 래핑되어 PHP에 대한 인터페이스를 제공합니다. PHP에서 네트워크 프로그래밍 단계가 크게 줄어듭니다. 예: stream_socket_server 및 stream_socket_client는 서버/클라이언트 소켓을 직접 생성합니다(php에는 두 세트의 소켓 작업 기능이 있습니다). wm은 전자를 광범위하게 사용하며 시작 프로세스는 다음과 같습니다(댓글은 매우 자세함):
public static function runAll() { // 初始化环境变量 self::init(); // 解析命令 self::parseCommand(); // 尝试以守护进程模式运行 self::daemonize(); // 初始化所有worker实例,主要是监听端口 self::initWorkers(); // 初始化所有信号处理函数 self::installSignal(); // 保存主进程pid self::saveMasterPid(); // 创建子进程(worker进程)并运行 self::forkWorkers(); // 展示启动界面 self::displayUI(); // 尝试重定向标准输入输出 self::resetStd(); // 监控所有子进程(worker进程) self::monitorWorkers(); }프로세스의 핵심 사항에 대해 이야기해 보겠습니다. 1 . 기본 프로세스 이름, 로그 경로, 초기화 타이머 등의 환경 변수를 초기화합니다. 2. 주로 $argc 및 $argc를 사용하여 명령줄 매개변수를 구문 분석합니다. C 언어로;
#🎜 🎜#3. 현재 터미널에서 벗어나기 위해 데몬 프로세스를 생성합니다. (2년 전만 해도 대부분의 사람들은 PHP를 데몬으로 사용할 수 없다고 생각했습니다. 사실 이것은 오해입니다. 실제로 Linux에서 PHP의 프로세스 모델은 매우 안정적입니다. 이제 비즈니스에 wm을 적용하는 것은 매우 성숙해졌습니다. 국내 한 회사는 매일 수억 건의 주문 및 결제 통화를 처리하므로 걱정하지 않으셔도 됩니다. 따로); 서버가 많고 모니터링이 설정되지 않았습니다. 다중 프로세스 모델은 IO 다중화입니다.) 신호 처리 기능을 등록하십시오. 주요 프로세스의 경우
6. 메인 프로세스 PID를 저장합니다. 시스템이 실행 중일 때 터미널에서 시스템 상태를 확인하거나 종료 또는 다시 시작 명령을 실행할 수 있습니다. 따라서 메인 프로세스 PID를 알아야 합니다. 이 명령은 실제로 실행을 위해 현재 터미널 아래에 새로운 하위 프로세스를 생성하므로 이때 신호 처리 기능인 SIGNAL을 보내려면 기본 프로세스 PID를 알아야 합니다. 신호를 캡처하고 콜백을 통해 실행합니다.
7. 하위 프로세스를 생성하고 현재 프로세스 사용자(루트)를 설정합니다. 다중 프로세스 모델에서는 두 가지 유형의 하위 프로세스가 각각 서로 다른 서버 주소를 수신합니다. 기본 프로세스에서는 서버만 생성하고 수신을 설정하지 않으며 지정된 수의 서버를 생성하지도 않습니다.
한 프로세스에서 동일한 소켓을 여러 번 생성하면 오류가 보고되기 때문입니다. 작업자 수는 실제로 소켓 수, 즉 소켓의 하위 프로세스 수입니다. 상위 프로세스 컨텍스트를 상속하지만 특정 소켓 이벤트만 수신합니다. ;
8 하위 프로세스에서는 이벤트를 수신하기 위해 서버 소켓을 등록하고 확장된 이벤트를 사용하여 IO 재사용을 달성하고 데이터 읽기 콜백을 등록할 수 있습니다.
9. 입력 출력 리디렉션도 등록합니다.
10. 기본 프로세스는 하위 프로세스의 상태를 모니터링하고 무한 루프에서 pcntl_signal_dispatch() 함수를 호출하여 하위 프로세스의 종료 상태를 캡처합니다. 이 함수는 하위 프로세스가 종료될 때까지 차단됩니다.
workerman 관련 지식을 더 보려면 workerman 튜토리얼 열을 주목하세요.
위 내용은 워커맨 소스코드 분석 시작과정에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!