We know that processes and threads consume memory and other system resources, and they need to context switch. Most modern servers can handle hundreds of processes or threads simultaneously, but performance will degrade when memory is exhausted, and frequent context switches will occur during times of high IO load.
The conventional way to deal with the network is to create a process or thread for each connection. This method is easy to implement, but difficult to expand.
So how does Nginx do it? How Does NGINX Work?
After nginx is started, there will be a master process and multiple worker processes. The master process is mainly used to manage worker processes, including: receiving signals from the outside world, sending signals to each worker process, monitoring the running status of the worker process, and automatically restarting a new worker process when the worker process exits (under abnormal circumstances). . 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, and a worker process cannot process requests from other processes. The number of worker processes can be set. Generally, we will set it to be consistent with the number of CPU cores of the machine. The reason for this is inseparable from the process model and event processing model of nginx. The process model of nginx can be represented by the following figure:
As you can see, the worker process is managed by the master. The master process will receive signals from the outside world and then do different things based on the signals. So if we want to control nginx, we only need to send a signal to the master process. For example, ./nginx -s reload is to restart nginx. This command will send a signal to the master process. First, after receiving the signal, the master process will reload the configuration file, then start a new process, and send the signal to all old processes. process sends a signal that they can retire honorably. After the new process is started, it begins to receive new requests, while the old process will no longer receive new requests after receiving the signal from the master, and after all unprocessed requests in the current process are processed, , and then exit.
So, how does the worker process handle requests?
As we mentioned earlier, worker processes are equal, and each process has the same opportunity to process requests. When we provide http service on port 80 and a connection request comes, each process may handle the connection. How to do this? First, each worker process is forked from the master process. In the master process, the socket that needs to be listened is first established, and then multiple worker processes are forked, so that each worker process can accept this socket (of course It is not the same socket, but the socket of each process will monitor the same IP address and port. This is allowed in the network protocol). nginx provides an accept_mutex thing. From the name, we can see that this is a shared lock added to accept. With this lock, there will only be one process connecting accpet at the same time. accept_mutex is a controllable option that we can turn off explicitly. It is turned on by default. When a worker process accepts the connection, it starts reading the request, parsing the request, processing the request, generating data, and then returns it to the client, and finally disconnects the connection. This is what a complete request looks like. We can see that a request is completely processed by the worker process, and is only processed in one worker process.
So, what are the benefits of nginx adopting this process model?
1) Each worker process is independent and does not require locking, eliminating lock overhead and making programming simple.
2) The processes are independent of each other and do not affect each other. After one process exits (for example, an exception occurs), other processes will work as usual and the service will not be interrupted.
3) No context switching, reducing unnecessary system overhead
Nginx adopts an event-driven processing mechanism, which is a system call like epoll in Linux. Multiple events can be monitored at the same time, and a timeout can be set. Within the timeout, if an event is ready, the prepared event will be returned. In this way, as long as an event is ready, we will process it, and only when all events are not ready, we will block and wait in epoll. In this way, we can perform high-concurrency processing. We continuously switch between requests. The switching is because the event is not ready and we actively give up. There is no cost to switching here and can be simply understood as loop processing of multiple prepared events.
Compared with multi-threading, this event processing method has great advantages. There is no need to create threads, each request occupies very little memory, there is no context switching, and event processing is very lightweight. No matter how many concurrencies there are, it will not lead to unnecessary waste of resources (context switching). More concurrency will only occupy more memory, which is also the main reason why nginx has efficient performance.
The following is excerpted from Nginx official website:
When an NGINX server is active, only the worker processes are busy. Each worker process handles multiple connections in a non-blocking fashion, reducing the number of context switches.
Each worker process is single-threaded and runs independently, grabbing new connections and processing them. The processes can communicate using shared memory for shared cache data, session persistence data, and other shared resources.
Each NGINX worker process is initialized with the NGINX configuration and is provided with a set of listen sockets by the master process.
The NGINX worker processes begin by waiting for events on the listen sockets (accept_mutex and kernel socket sharding). Events are initiated by new incoming connections. These connections are assigned to a state machine – the HTTP state machine is the most commonly used, but NGINX also implements state machines for stream (raw TCP) traffic and for a number of mail protocols (SMTP, IMAP, and POP3).
Copyright Statement: This article is an original article by the blogger and may not be reproduced without the blogger's permission.
The above introduces the working mechanism of Nginx2, including various aspects. I hope it will be helpful to friends who are interested in PHP tutorials.