La colonne suivante présentera le processus de démarrage de l'analyse du code source Workerman à partir de la colonne Tutoriel Workerman J'espère que cela sera utile aux amis dans le besoin !
ouvrier
Version : 3.1.8 (linux)
Modèle : GatewayWorker (le modèle Worker peut lui être comparé)
Remarque : Seule la partie explication du code est publiée, et la source est donné sous la forme d'un nom de fichier. Vous pouvez le vérifier par vous-même
Workerman n'a initialement développé que la version Linux, win a été ajouté plus tard et il s'exécute en mode ligne de commande (cli).
Modèle multi-processus
Le processus de travail, le maître, la passerelle et la passerelle de travail sont principalement utilisés pour traiter les événements IO et enregistrer l'état du lien client. .Envoyer des requêtes de traitement de données à Worker et à d'autres tâches. Worker est un traitement de logique métier complet. Le premier nécessite beaucoup d'E/S et le second nécessite beaucoup de calcul. Ils communiquent via le réseau et Worker enregistrent les adresses de communication par paires. est très pratique pour un déploiement distribué. Si le volume de traitement métier est important, vous pouvez simplement ajouter des services Worker.
Ils ont un processus parent (Maître) chargé de surveiller, de surveiller l'état du processus enfant, d'envoyer des signaux au processus enfant et d'accepter les commandes et les signaux du terminal . Le processus parent peut être considéré comme le point d'entrée après le démarrage de l'ensemble du système.
Démarrer l'analyse des commandes
Comme il fonctionne en mode commande (cli) (notez la différence avec fpm, ce dernier gère les requêtes du page Web), il doit y avoir une commande d'analyse du script de démarrage. Par exemple, la version 3.x (auparavant, la valeur par défaut était démon) ajoute un paramètre -d pour indiquer que le processus démon est en cours d'exécution. Lors de l'analyse de ce paramètre, définissez self : :$daemon = true, puis fork Le processus enfant peut quitter le groupe de processus actuel, définir le chef du groupe de processus, etc.
Il y a deux paramètres très importants $argc et $argc Le premier représente le nombre de paramètres, et le second est un tableau qui enregistre tous les paramètres de la commande, tel que : sudo php start.php start. -d, $argv est un tableau([0]=>start.php, [1]=>start, [2]=>-d), et l'analyse utilise principalement $argv.
Le démarrage effectue principalement les étapes suivantes :
1. Contient le chargeur automatique Autoloader pour charger les fichiers de démarrage sous chaque application
2. Définissez le répertoire racine _appInitPath ; 🎜>
3. Analysez, initialisez les paramètres et exécutez les commandes correspondantes. Ce qui suit est l'implémentation spécifique (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; } }
Worker::runAll()
La programmation du socket de PHP est en fait similaire au C. Ce dernier reconditionne le socket et fournit L'interface est fournie vers PHP, et les étapes de programmation réseau sous PHP sont grandement réduites. Par exemple : stream_socket_server et stream_socket_client créent directement un socket serveur/client (php a deux ensembles de fonctions d'opération de socket). wm utilise largement le premier, et le processus de démarrage est le suivant (les commentaires sont très détaillés) :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(); }
6. Enregistrez le PID du processus principal. Lorsque le système est en cours d'exécution, nous pouvons vérifier l'état du système dans le terminal ou exécuter des commandes d'arrêt ou de redémarrage. La communication se fait via le processus principal, nous devons donc connaître le PID du processus principal. Nous savons qu'il faut en taper un dans le terminal. La commande exécutable crée en fait un nouveau sous-processus sous le terminal actuel pour l'exécution, nous devons donc connaître le PID du processus principal pour envoyer SIGNAL au processus principal WM à ce moment-là. La fonction de traitement capture le signal et l'exécute via un rappel.
7. Créez un processus enfant et définissez l'utilisateur du processus actuel (root). Dans le modèle multi-processus, deux types de sous-processus écoutent respectivement différentes adresses de serveur. Dans le processus principal, nous créons uniquement des serveurs et ne configurons pas l'écoute, et nous ne générons pas non plus un nombre spécifié de serveurs.
La raison est que si nous créons le même socket plusieurs fois dans un processus, une erreur sera signalée. Le nombre de travailleurs est en fait le nombre de sockets, c'est-à-dire le nombre de processus enfants du socket. .Le processus enfant hérite du contexte du processus parent, mais n'écoute que les événements de socket spécifiques ;
8 Dans le processus enfant, enregistrez le socket du serveur pour écouter les événements et utilisez un événement étendu pour réaliser la réutilisation des E/S, enregistrez-vous. rappels de lecture de données, et également enregistrer les connexions de socket ;
9. Redirection d'entrée et de sortie
10. ) fonctionne dans une boucle infinie pour capturer l'état de sortie du sous-processus. Cette fonction se bloquera jusqu'à ce qu'un processus enfant se termine
Pour plus de connaissances sur Workerman, veuillez prêter attention au tutoriel Workerman colonne.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!