Nginx-explain its principle in detail

Insert picture description here

Nginx process model analysis

Before introducing the Nginx process model, let's explain some common terms to everyone, which can help us better understand the Nginx process model. As a web server, the original intention of the design is to be able to handle more client requests. Generally speaking, there are three ways to complete parallel processing of requests, multi-process, multi-thread, and asynchronous.

Multi-process

Each time the server receives a client request, the main process will generate a child process to establish a connection with the request to interact, until the connection is disconnected, the child process will end

The advantage is that each sub-process is independent of each other, and each client request is not interfered with each other.

The disadvantage is that spawning a child process requires memory copying, and will generate a certain amount of additional overhead in resources and time. If there are more requests, it will put a certain pressure on system resources

Insert picture description here

Multi-threaded

The multi-threading mode is very similar to the multi-process mode. Each time the server receives a client request, it generates a thread to interact with the client. The cost of generating a thread is much smaller than that of a process, so the multi-threading method reduces the web server's requirements on system resources to a certain extent.

The disadvantage is that there is memory sharing between multiple threads and mutual influence between each other

Insert picture description here

Asynchronous

The asynchronous method is completely different from the two methods mentioned above. Regarding the asynchronous aspect, there are several concepts of synchronization and asynchronous; blocking and non-blocking. Let me explain together here.

We understand very well about synchronization and asynchrony. Synchronous mechanism means that after the sender sends a request, it needs to wait for the receiver to return a response before sending the next request. In the asynchronous mechanism, after the sender sends the request, it does not wait for the receiver to respond to the request and then continues to send the next request.

Insert picture description here

Insert picture description here

Blocking and non-blocking, mainly refers to the blocking and non-blocking methods of socket reading and writing data. The essence of Socket is actually IO operation. There is a sending buffer and a receiving buffer in the kernel of every TCP Socket. For blocking mode, if the receiving buffer is empty, the thread of the socket read method will block until data enters the receiving buffer. For writing data to the socket, if the length of the data to be sent is greater than the free length of the sending buffer, the write method will enter blocking.

Insert picture description here

Insert picture description here

At first glance, the explanation of these four concepts will instantly feel big, and it is often said that synchronous and asynchronous are equivalent to blocking and non-blocking. In fact, it is very simple to distinguish them. The main difference between synchronous and asynchronous and blocking non-blocking is that it targets different objects.

Synchronous and asynchronous is for the caller. After the caller initiates a request, it is synchronous to wait for the callee's feedback, and it is asynchronous without waiting to do other things.

Blocking non-blocking is for the callee. After the callee receives a request, it gives feedback after completing the requested task is blocking, and it is non-blocking to give feedback directly after receiving the request and then do the task.

For non-blocking mode, the goal is achieved through event triggering. We can think that there is an I/O scheduling thread in the bottom layer of NIO. It constantly scans the buffer of each Socket. When it finds that the write buffer is empty, it will generate a Socket writable event, and the program can Write the data to the Socket. If you can't finish writing at a time, wait for the next writable event notification; on the contrary, when it finds that there is data in the buffer, it will generate a Socket readable event, and the program can read data from the Socket after receiving this notification event Up.

Then based on these concepts, four concepts are introduced: synchronous blocking, synchronous non-blocking, asynchronous blocking, asynchronous non-blocking

Synchronous blocking: After the sender sends a request to the receiver, it has been waiting for the receiver to respond; if the IO operation performed by the receiver when processing the request cannot get the result immediately, it has been waiting for the result to return before responding to the sender. Has been in a blocked state during the period;

Insert picture description here

Synchronous non-blocking: After the sender sends a request to the receiver, it has been waiting for a response. When the receiver is performing an IO operation, it does not need to wait to do other things directly, and because the result has not been obtained, the sender is still waiting. After the receiver obtains the io operation, it responds to the sender with the result, and the receiver enters the next request process

Insert picture description here

Asynchronous blocking: After the sender sends a request to the receiver, it can proceed with other operations without waiting for a response. If the IO operation performed by the receiver when processing the request cannot obtain the result immediately, it will wait for the result to be returned and then respond to the sender

Insert picture description here

Asynchronous non-blocking: After the sender sends a request, it can continue to do other things without waiting for a response. If the IO operation performed by the receiver when processing the request cannot get the result immediately, it does not wait, but does other things. When the io operation is completed, the result is notified to the receiver, and the receiver then responds to the sender

Insert picture description here

Nginx server request processing process

Nginx combines a multi-process mechanism and an asynchronous mechanism to provide external services. After the
Nginx service is started, a main process and multiple worker processes will be generated.
The master process is mainly used to manage the worker process, including: receiving signals from the outside world, sending signals to each worker process, monitoring the running status of the worker process, and automatically restarting the new worker process when the worker process exits (under abnormal conditions)

Basic network events are handled in the worker process. Multiple worker processes are peer-to-peer, they compete equally for requests from clients, and each process is independent of each other. A request can only be processed in one worker process. A worker process cannot handle the requests of other processes. The number of worker processes can be set. Generally, we will set it to be the same as the number of machine cpu cores.

What is the role of the master process?
Read and verify the configuration file nginx.conf; manage the worker process;

What is the role of the Worker process?

Each worker process maintains a thread (to avoid thread switching) to handle connections and requests; note that the number of worker processes is determined by the configuration file, generally related to the number of CPUs (conducive to process switching), there are several configurations Worker process.

Insert picture description here

Hot deployment

The master manages the worker process, so we only need to communicate with the master process. The master process will receive signals from the outside world, and then do different things according to the signals, such as the one we used earlier

./sbin/nginx -c conf/nginx.conf -s reload

When executing this command, the master starts a new Nginx process after receiving this signal. After the new Nginx process parses the reload parameter, it knows that it is necessary to control Nginx to reload the configuration file, and it will send a signal to the master process. , And then the master will reload the configuration file, start the new worker process, and send a signal to all the old worker processes to tell them that they can retire, and the new worker can receive new requests with the new configuration file after it is started – Principle of hot deployment

Insert picture description here

How does the worker process handle requests?

We basically know what is done inside nginx when operating nginx, so how does the worker process handle requests? In Nginx, all worker processes are equal, and each process has the same opportunity to process each request. When we provide http service on port 80, a connection request comes, and each process may handle the connection.

The worker process forks from the master process. In the master process, the socket that needs listen is first established, and then multiple worker processes are forked. When a new connection request comes, the worker process can handle it, in order to avoid surprise Effect, the worker process must first seize the accept_mutex, which is the mutual exclusion lock, before processing the request. After obtaining the lock successfully, it can resolve and process the request. After the request is processed, it is returned to the client.

Insert picture description here
Insert picture description here

Some of the benefits brought by the process model processing method are: the processes are independent, that is, a worker process exits abnormally, other worker processes will not be affected; in addition, independent processes will also avoid some unnecessary locks Operation, this will improve processing efficiency, and development and debugging will be easier.

The worker process will compete to monitor the client's connection request: this method may cause a problem, that is, all requests may be competitively acquired by a worker process, resulting in other processes being relatively idle, and a certain process will be busy Status, this status may also result in failure to respond to the connection in a timely manner and discard requests that are capable of processing. This unfair phenomenon needs to be avoided, especially in a highly reliable web server environment.

In response to this phenomenon, Nginx uses a value for whether to enable the accept_mutex option. The ngx_accept_disabled flag controls whether a worker process needs to compete for the accept_mutex option, and then obtain the accept event.

ngx_accept_disabled value: one-eighth of the total number of all connections in a single nginx process, minus the remaining number of idle connections, to get this ngx_accept_disabled.
When ngx_accept_disabled is greater than 0, no attempt will be made to acquire the accept_mutex lock, and ngx_accept_disabled will be decremented by 1, so every time it is executed, it will decrement by 1 until it is less than 0.

Not acquiring the accept_mutex lock is equivalent to giving up the opportunity to acquire connections. Obviously, it can be seen that when there are fewer idle connections, the larger the ngx_accept_disable, the more opportunities are given up, so that other processes have the opportunity to acquire the lock. Bigger. If you do not accept, your own connection will be controlled, and the connection pool of other processes will be used. In this way, nginx controls the balance of connections between multiple processes.

Ok~ This article first introduces here, if you have any questions, please leave a message~

Insert picture description here

Guess you like

Origin blog.csdn.net/liuxingjiaoyu/article/details/112917244