Foreword:
“
Server programs usually control the work of the server through corresponding configuration files. In many cases, the configuration file will be modified frequently. When making it take effect, we hope that the program will not be restarted and the normal service of the server will not be affected. So the so-called “hot loading” of configuration files has become a very important function, and in this regard, nginx has set a very good example for us, which is worth learning and learning from.
analyze:
“
When nginx is in normal service, we execute ./nginx in the program directory of nginx
?sreload, to reload the configuration file. The function of -s is to send a signal to the master process. In addition to the reload function, stop, reopen, etc. can also be used. Specifically, you can view it through -h.
When executing ./nginx ?s
After reload, save the “reload” string through ngxs_signal, and then pass it through ngx_signal_process
To send a signal to the currently running nginxmaster process.
if (ngx_signal) {
“
return ngx_signal_process(cycle, ngx_signal);
}
By reading the code, we can see that sending a signal to the currently running nginx process is actually restarting a copy of nginx, but this nginx will not start up as a server, it will exit after sending the signal for us. Therefore, some controls of nginx do not require us to use kill to operate. nginx has packaged them for us, which is convenient for us to use.
Specifically, how does nginx help us send signals? In fact, it is very simple. We know that nginx has a pid file, which records the pid of the currently running nginxmaster process, so the program will get the pid of the process through this file, and the signo corresponding to the signal string, and finally use kill to complete the signal sent.
The Nginx initialization phase initializes the signal operation through the ngx_init_signals function. A signals array is defined in ngx_process.c.
typedef struct {
int signo; // signal value
char *signame; // Literal name corresponding to the signal value
char *name; // alias under nginx
void (*handler)(int signo); // signal processing function
} ngx_signal_t;
We see that “reload” is actually the encapsulation of the SIGHUP signal, that is to say, we can directly send the SIGHUP signal to nginx through kill to complete the reload operation.
Here we focus on the signal processing function: ngx_signal_handler.
So when we execute nginx ?s reload, ngx_signal_handler will be executed.
In ngx_signal_handler, ngx_process indicates the type of the current process. During signal processing, the processing is different for different processes. Here, switch
case to distinguish. We mainly focus on the masterprocess, which is of type NGX_PROCESS_MASTER.
casengx_signal_value(NGX_RECONFIGURE_SIGNAL):
ngx_reconfigure = 1;
action = “, reconfiguring”;
break;
We found that the global variable ngx_reconfigure in the current process is set to 1, so that ngx_recOnfigure==1 is detected in the for loop of ngx_master_process_cycle, and the operation of reloading configuration begins.
The next steps are obvious. Start a new process through ngx_start_worker_processes, while the previous process sends a signal through ngx_signal_worker_processes to “gracefully” shut down. The so-called graceful shutdown means that the current process that actually processes the request will wait until the process is completed before exiting, and the current process stops at the same time. listen, no longer accept new requests.