Nginx process structure
Nginx has two types of process structures: single-process and multi-process. By default, there is only one worker process after compilation and installation, which can be configured in nginx.conf.
Recommended: The number of worker processes should be equal to the number of CPU cores. For high-traffic concurrent scenarios, increase the number of worker processes to 2 CPU cores
A single process can only be used for development debugging; Multi-process ensures that Nginx is robust enough to take advantage of multi-core features.
Why multi-process and not multi-thread?
The core purpose of Nginx is to maintain high availability and reliability. If Nginx uses a multi-threaded structure, threads share an address space, and if a third party module raises a segment error in the address space or an address out of bounds, it will cause the entire Nginx process to hang up. This is not the case when using the multi-process model!
Adjust the number of work processes?
After nginx is compiled and installed, one main process and one worker process are started by default. This does not meet nginx performance requirements. We can modify the nginx configuration file to set the number of worker processes:
#user molong;worker_processes auto; Error_log logs/error.log; // The default value is 1. If you change the value to auto, you can set the number of working processes according to the number of CPU cores. error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid;Copy the code
If set manually, you can run lscPU to check the number of CPU cores:
Two. Semaphore
2.1. What is a semaphore?
Semaphore is one of the IPC mechanisms used to implement computer resource sharing, which is essentially a counter. Semaphores are methods to implement mutually exclusive or shared resource access in a multi-process environment, which can be used to ensure that two or more critical code segments are not called concurrently.
A process/thread must acquire a semaphore before entering a critical code segment; Once the critical piece of code is complete, the process must release the semaphore. Other threads that want to enter the critical code segment must wait until the first process releases the semaphore.
Application form:
-
Mutually exclusive access to a critical resource that can be used by only one process at a time
-
Processing of multiple shared resources, in which the semaphore plays the role of recording the number of idle resources
We can view the semaphores supported by Linux by using kill -l:
2.2. Common semaphores:
code | Serial number | note |
---|---|---|
SIGCHLD | 17 | The parent receives this signal when the child terminates. |
SIGQUIT | 3 | Similar to SIGINT, but controlled by the QUIT character (usually Ctrl-/). A core file is generated when a process exits due to SIGQUIT, which is similar to a program error signal in this sense. |
SIGTERM | 15 | Terminate signals, which, unlike SIGKILL, can be blocked and processed. (It won’t end immediately) |
SIGKILL | 9 | Used to terminate the program immediately. This signal cannot be blocked, processed, or ignored. |
SIGHUP | 1 | This signal is sent when the user terminal connection (normal or abnormal) has ended, usually when the terminal’s control process has ended, to inform individual jobs in the same session that they are no longer associated with the control terminal. |
SIGUSR1 | 10 | Leave it to the user |
SIGUSR2 | 12 | Leave it to the user |
SIGWINCH | 28 | Ignore signal emitted when the window size changes. |
More detailed information can see the blogger article: blog.xujiuming.com/ming/8b4775…
2.3. Semaphore use
In my daily life, I use the kill command to kill a process via PID. In fact, I send a semaphore to the process:
kill-9 Nginx main process PIDCopy the code
As shown in the figure:
Here 9 is the SIGKILL semaphore number. This semaphore is the process that violently kills Nginx and will cause problems if it is currently reading or writing data or performing operations. The recommended semaphore is SIGTERM, which is relatively mild.
We can also see that the SIGKILL signal can only kill the master process, while the worker process still survives. But it is ok if we use a command without -9, the 15 (SIGTERM) semaphore that the kill command sends by default.
Normally, to shut down a process, the system sends the SIGTERM signal first. After a short period of time, the system sends the SIGKILL signal if the process is not shut down.
Nginx and semaphores
Nginx is controlled by signals, such as shutdown, restart, etc. Nginx signal is a mechanism for communication between Nginx processes. The master process controls multiple worker child processes through signals.
3.1. The role of the master process
The master process of nginx is used to manage the master process.
-
Read and verify configuration information
-
Manage worker processes that provide services and send signals to each worker process;
-
Monitor the running status of worker processes. When the worker process exits abnormally, send CHLD signal to the master process, and the master process creates new worker processes to keep the number of worker processes unchanged
It should be noted that the master process does not respond to user requests. What really matters is that the worker process responds to user requests.
3.2. Received semaphore
Then look at the semaphore interfaces of the main and worker processes.
A semaphore | role | master | worker |
---|---|---|---|
TERM | Termination signal. This is the default signal type sent by the kill command. | receive | receive |
INT | Interrupt signal. The effect is the same as when ctrl-C is pressed on the terminal. Close the process directly, regardless of whether the process is being requested | receive | receive |
QUIT | Gracefully close the process, waiting for requests to end in the current process. | receive | receive |
HUP | Load the new configuration, the master process remains unchanged, and gradually stop the work without requests and start the new worker process | receive | |
USR1 | Re-open the log file, log backup, log cutting when used. | receive | receive |
USR2 | Used when running nginx processes need to be smoothly upgraded | receive | |
WINCH | Gracefully and calmly close worker processes (generally used with USR2) | receive | receive |
3.3. Command lines and semaphores
We are executing nginx commands that send a series of semaphores:
The command | A semaphore | role |
---|---|---|
reload | HUP | Reload the configuration file |
reopen | USR1 | Rereading log files |
stop | TERM | Close quickly, regardless of whether or not a request is being processed |
quit | QUIT | Graceful shutdown, Nginx completes accepted connection requests before exiting |
Reload configuration file flow
We know that when we perform nginx -s reload, nginx is not down, so what is the process of reloading the configuration file? Here is an introduction:
-
Send HUP signal to master (reload command)
-
Master Checks whether the configuration file is correct
-
The master process opens the listening port
-
The master process starts the new worker child process with the new configuration file
-
The master process sends the QUIT signal to the old worker child process
-
The old worker process closes the listener handle and closes the process after processing the current connection
Hot deployment process
When an old version of nginx is replaced by a new version of nginx, the nginx service must be cancelled and restarted. If a user is accessing the nginx service, the user will be disconnected, which affects user experience. In this case, hot deployment is required to smooth the replacement.
5.1. Hot Deployment process
The general process is as follows:
-
Replace the old nginx file with the new nginx file
-
Sends the USER2 signal to the master process
-
The master process modifies the PID file and suffixes it with. Oldbin
-
The master process starts the new master process with the new nginx file
-
Send WINCH signal to the old master process, and the old worker child process exits (at this time, the master process does not exit, so as to ensure the rollback in case of error)
-
Rollback case: Send HUP to the old master (according to the old configuration file, pull up the child process), send QUIT to the new master (new offline)
5.2. Hot deployment demonstration
Note: New versions of Nginx require the same directory, version, and configure parameters as older versions.
Step 1: Backup, hot deployment is mainly to replace nginx executable files, to avoid problems, first backup the old nginx binaries.
➜ sbin ll Total usage 23m-rwxrwxr-x 1 molong molong 12M Oct 9 10:55 nginx# new executable
-rwxrwxr-x 1 molong molong 12M Oct 12 15:06 nginx.bak Old executable file
Copy the code
Step 2: Start a new nginx process. Here, the old version of Nginx stops receiving requests by sending SIGUSR2 signals to the running master process (the old version of Nginx) and the new version of Nginx takes over
sudo kill-USR2 Indicates the PID of the main nginx processCopy the code
The execution result is shown as follows:
Nginx. pid and nginx.pid. Oldbin files record the pid of the old and new nginx master processes.
Step 3: Stop the old nginx worker process, but do not stop the old Nginx master process, otherwise it cannot be rolled back
sudo kill-s SIGWINCH Indicates the main PROCESS PID of the old NginxCopy the code
The result is shown below:
At this point, we can verify that the new nginx meets our requirements. If not, we can roll back the process. If yes, we can terminate the old nginx master process.
Kill -s SIGQUIT Main PROCESS PID of the old NginxExit the old nginx master process
Copy the code
5.3. Rollback demo
When it is found that the new nginx does not meet the requirements, a rollback is required. A SIGHUP signal can be sent to the old Nginx master, which will pull up the old configuration file and start the worker child process.
sudo kill-s SIGHUP Main PROCESS PID of old NginxEquivalent to reloading the configuration file
Copy the code
Results:
Then the new Nginx exits the problem.
sudo kill-s SIGQUIT Indicates the main PROCESS PID of the old NginxCopy the code
Results:
Extension: segment error
What is a segment error?
Once an out-of-bounds access occurs in a program, the CPU will generate corresponding protection, resulting in a segmentation fault. According to the above explanation, a segment fault is the access to inaccessible memory.
The memory area is either nonexistent, protected by the system, or may be missing or corrupted.
What are the causes of segment errors?
-
Non-associative null Pointers – this is a special case by memory management hardware
-
Attempted to access a non-existent memory address (in the process’s address space)
-
Programs trying to access memory have no rights (e.g., kernel-structured process context)
-
An attempt to write (a code snippet, for example) to read-only memory.