diagram One: Nginx startup and memory application process Analysis
No program can be separated from start-up and configuration parsing. NGX's code is inseparable from the two core data structures of ngx_cycle_s and ngx_pool_s, so let's analyze it before starting.
The memory application process is divided into 3 steps
If the requested memory is less than the space remaining in the current block, it is allocated directly in the current block.
If the current block space is insufficient, call Ngx_palloc_block to assign a new block and then link the new block to D.next, and then assign the data.
If the size of the request is greater than the maximum value of the current block, then call Ngx_palloc_large directly to allocate a chunk, and link to the Pool→large linked list
The memory allocation process is illustrated below
(Image from Network)
In order to better understand the above diagram, you can refer to the 2 data structures at the end of the text: ngx_pool_s and ngx_cycle_s.
Knowing the two core data structures, we formally enter the main function, and the main function executes as follows
Call Ngx_get_options () to parse the command parameters;
Call Ngx_time_init () to initialize and update time, such as global variable ngx_cached_time;
Call Ngx_log_init () to initialize the log, such as initializing the global variable Ngx_prefix, to open the log file ngx_log_file.fd;
Clear 0 global variable ngx_cycle, and create a memory pool of size 1024B for Ngx_cycle.pool;
Call NGX_SAVE_ARGV () to save the command-line arguments to global variables ngx_os_argv, NGX_ARGC, NGX_ARGV;
Call Ngx_process_options () to initialize the ngx_cycle prefix, Conf_prefix, Conf_file, conf_param fields;
Call Ngx_os_init () to initialize system related variables, such as memory page size ngx_pagesize, ngx_cacheline_size, maximum number of connections ngx_max_sockets, etc.;
Call Ngx_crc32_table_init () to initialize the CRC table (the subsequent CRC check is done by checking the table, high efficiency);
Call Ngx_add_inherited_sockets () to inherit sockets:
Parse environment variable Nginx_var = "NGINX" in sockets, and save to ngx_cycle.listening array;
Set ngx_inherited = 1;
Call Ngx_set_inherited_sockets () to set the sockets in the ngx_cycle.listening array;
Initializes the index of each module and calculates the Ngx_max_module;
Call Ngx_init_cycle () to initialize;
The initialization is mainly carried out on the ngx_cycle structure;
If there is a signal, enter the ngx_signal_process () processing;
Call Ngx_init_signals () to initialize the signal, mainly to complete the signal processing program registration;
If there is no inheritance sockets, and the daemon identity is set, call Ngx_daemon () to create the daemon;
Call Ngx_create_pidfile () to create the process record file; (non-ngx_process_master = 1 process, do not create the file)
Enter the process main loop;
In the case of ngx_process_single=1 mode, call Ngx_single_process_cycle () into the process loop;
Otherwise, the Master-worker mode calls Ngx_master_process_cycle () into the process loop;
In the main function execution, there is a very important function ngx_init_cycle, what does this phase do? The following analysis Ngx_init_cycle, the initialization process:
Update timezone and Time
Create a memory pool
allocating memory to cycle pointers
Save installation path, configuration file, startup parameters, etc.
Initialize Open file handle
Initializing shared memory
Initializing the connection queue
Save hostname
Call the Create_conf method of each Ngx_core_module
Parsing the configuration file
Call the Init_conf method of each Ngx_core_module
Open a new file handle
Create shared memory
Processing a listening socket
Creating a socket for listening
Call the Init_module of each module
Figure Two: Master process working principle and work Engineering
The following procedures are performed in the Ngx_master_process_cycle function, starting the process:
Temporarily block all signals that NGX need to process
Set process Name
Start a worker process
Start the cache management process
Enter the loop to start processing the relevant signal
Master Process Work process
Set the work process exit wait time
Hang up and wait for the new signal to come
Update Time
Restart worker Process If there is a worker process because the SIGCHLD signal is exited
The master process exits. If all worker processes are exited and receive a SIGTERM signal or SIGINT signal or sigquit signal, etc., the master process begins processing the exit
Handling Sigterm Signals
Process the sigquit signal and close the socket
Handling Sighup Signals
Smooth upgrade, restart worker process
Not a smooth upgrade, requires a re-read configuration
Process Restart 10 process SIGUSR1 signal reopen all Files 11 process SIGUSR2 signal Hot code replacement, execute new program 12 process sigwinch signal, no longer process any request
Figure three: How Worker processes work
Start by executing the ngx_start_worker_processes function:
Find the pit bit in the ngx_processes array first if (Ngx_processes[s].pid = =-1) {break;}
Process-related structure initialization work
Create Pipeline (Socketpair)
Set the pipeline to non-blocking mode
Set the pipeline to asynchronous mode
To set the owner of an asynchronous I/O
If exec executes, this FD is not passed to the process created by exec
Fork to create the child process. After a successful creation, the child process executes the relevant logic: proc (cycle, data).
Set Ngx_processes[s] Related properties
Notifies the child process that a new process has been created Ngx_pass_open_channel (cycle, &ch);
Next is the Ngx_worker_process_cycle worker process logic
Ngx_worker_process_init
Initializing environment variables
Set process priority
Set the limit on the number of file handles
Setting up the Core_file file
User group settings
CPU Affinity Settings
Set working directory
Set Random seed number
Initializing the Listening state
The Init_process method of each module is called to initialize
Close others ' fd[1] and keep others ' fd[1] used to communicate with each other. Own fd[1] receives the message of the master process.
Monitor Channel Read Events
Process mode
Process the piping signal. This process is done by Ngx_channel_handler, which is specifically explained in the pipeline event.
Threading mode
Ngx_worker_thread_cycle is a thread loop: In addition to processing the exit signal in the dead loop. The main work of the ngx_event_thread_process_posted, this piece of concrete content in the later talk about the event model, and then expand.
Processing of related signals
The master and Worker communication Principles are: