Home > PHP Framework > Workerman > body text

Detailed explanation of the startup process of workerman source code analysis

Release: 2019-11-26 14:26:33
forward
3708 people have browsed it

The following column workerman tutorial will introduce you to the startup process of workerman source code analysis. I hope it will be helpful to friends in need!

Detailed explanation of the startup process of workerman source code analysis

#workerman

Version: 3.1.8 (linux)

Model: GatewayWorker (the Worker model can be compared with it)

Note: Only part of the code to explain is posted, and the source is given in the form of a file name. You can check it out by yourself

workerman initially only developed the Linux version, win was added later, and is run based on the command line mode (cli).

Multi-process model

Worker process, Master, Gateway and Worker, Gateway is mainly used to process IO events and save client connection status. Send data processing requests to Worker and other tasks. Worker is a complete business logic processing. The former is IO-intensive and the latter is computing-intensive. They communicate through the network. Gateway and Worker register communication addresses in pairs, so It is very convenient for distributed deployment. If the business processing volume is large, you can simply add Worker services.

Detailed explanation of the startup process of workerman source code analysis

They have a parent process (Master) responsible for monitoring, monitoring the status of the child process, sending signals to the child process, and accepting commands and signals from the terminal. The parent process can be said to be the entry point after the entire system is started.

Start command parsing

Since it is running in command mode (cli) (note the difference with fpm, which handles requests from the web page) , there must be a startup script parsing command. For example, version 3.x (previously the default was daemon) adds a -d parameter to indicate that the daemon process is running. When parsed to this parameter, set self::$daemon = true, and then fork The child process can leave the current process group, set the process group leader, etc.

There are two very important parameters $argc and $argc. The former represents the number of parameters, and the latter is an array that saves all the parameters of the command, such as: sudo php start.php start -d, $argv is array([0]=>start.php, [1]=>start, [2]=>-d), and $argv is mainly used for parsing.

Startup mainly performs the following steps:

1. Include the automatic loader Autoloader and load the startup files under each Application;

2. Set the _appInitPath root directory;

3. Parse, initialize parameters, and execute corresponding commands.

The following is the specific implementation (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;
        }
    }
Copy after login

The walker code comments are very detailed. Here are some details:

1. Check the main process Survival: Logical AND operation in line 17. If the main process PID exists, signal 0 is sent to the process. In fact, no information is sent. It only detects whether the process (or process group) is alive, and also detects the current user. Do you have permission to send system signals?

2. Why is the main process PID saved? After the system starts, it runs away from the current terminal. If you want to execute shutdown or other commands, the command will be executed in another process. If we don't even know the process PID, then who should we send the signal to?

So the main process PID must be saved, and the main process is responsible for monitoring other child processes, so it is the entrance for us to continue operations.

Worker::runAll()

#php’s socket programming is actually similar to C. The latter re-wraps the socket and provides The interface is provided to PHP, and the steps of network programming under PHP are greatly reduced.

For example: stream_socket_server and stream_socket_client directly create server/client socket (php has two sets of socket operation functions). wm makes extensive use of the former. The startup process is as follows (the comments are very detailed):

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();
    }
Copy after login

Let’s just talk about the key points of the process:

1. Initialize environment variables, such as setting the main Process name, log path, initialization timer, etc.;

2. Parse command line parameters, mainly using $argc and $argc. The usage is the same as C language;

3. Generate daemon process, In order to break away from the current terminal (two years ago, most people thought that PHP could not be used as a daemon. In fact, this is a misunderstanding! In fact, the process model of PHP in Linux is very stable. Now the application of wm in business has been very mature. A domestic company handles hundreds of millions of connections every day. , used for order and payment calls, you can put away your worries);

4. Initialize all worker instances (note that this is done in the main process, it just generates a bunch of servers and does not set up monitors. More The process model is monitoring in the child process, that is, IO multiplexing);

5. Register the signal processing function for the main process;

6. Save the main process PID. When the system is running, we can check the system status in the terminal or execute shutdown or restart commands. Communication is through the main process, so we need to know the main process PID. We know to type one in the terminal. The executable command actually creates a new sub-process under the current terminal for execution, so we need to know the main process PID to send SIGNAL to the WM main process. At this time, the signal processing function captures the signal and executes it through a callback.

7. Create a child process and set the current process user (root). In the multi-process model, two types of sub-processes listen to different server addresses respectively. In the main process, we only create servers and do not set up listening, nor do we generate a specified number of servers.

The reason is that if we create the same socket multiple times in a process, an error will be reported. The number of workers is actually the number of sockets, that is, the number of child processes of the socket. The child process inherits the parent process context, but only listens Specific socket events;

8. In the child process, register the server socket to listen for events, and use an extended Event to achieve IO reuse, register data reading callbacks, and also register socket connections. Event callback;

9. Input and output redirection;

10. The main process monitors the status of the sub-process and calls the pcntl_signal_dispatch() function in an infinite loop to capture the exit status of the sub-process. This function will block until a child process exits;

For more workerman related knowledge, please pay attention to the workerman tutorial column.

The above is the detailed content of Detailed explanation of the startup process of workerman source code analysis. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:cnblogs.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template