Home Operation and Maintenance Nginx Why is nginx performance good?

Why is nginx performance good?

Jun 12, 2019 am 10:11 AM
nginx performance

Why is nginx performance good?

After nginx is started, it will run in the background as a daemon in a Unix system. The background process includes a master process and multiple worker processes. We can also manually turn off the background mode, let nginx run in the foreground, and configure nginx to cancel the master process, so that nginx can run in a single-process mode.

Obviously, we will definitely not do this in a production environment, so turning off the background mode is generally used for debugging. In the following chapters, we will explain in detail how to debug nginx.

So, we can see that nginx works in a multi-process manner. Of course, nginx also supports multi-threading. However, our mainstream method is still the multi-process method, which is also the default method of nginx. . There are many benefits to using multi-process in nginx, so I will mainly explain the multi-process mode of nginx.

As mentioned just now, 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.

After nginx starts, if we want to operate nginx, what should we do?

From the above we can see that 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 based on the signals. So if we want to control nginx, we only need to send a signal to the master process through kill. For example, kill -HUP pid tells nginx to restart nginx gracefully. We usually use this signal to restart nginx or reload the configuration. Because it restarts gracefully, the service is not interrupted. What does the master process do after receiving the HUP signal?

First, after receiving the signal, the master process will reload the configuration file, then start a new worker process, and send signals to all old worker processes to tell them that they can retire honorably.

After the new worker starts, it begins to receive new requests, while the old worker stops receiving new requests after receiving the signal from the master, and all unprocessed requests in the current process After the complete request processing is completed, exit.

Of course, sending signals directly to the master process is an older method of operation. After nginx version 0.8, it introduced a series of command line parameters to facilitate our management. For example, ./nginx -s reload is to restart nginx, and ./nginx -s stop is to stop nginx from running.

How to do it?

Let’s take reload as an example. We see that when executing the command, we start a new nginx process, and the new nginx process will know our purpose after parsing the reload parameter. It is to control nginx to reload the configuration file. It will send a signal to the master process, and then the next action is the same as if we directly sent the signal to the master process.

Now, we know what nginx does internally when we operate nginx. 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 of all, each worker process is forked from the master process. In the master process, the socket (listenfd) that needs to be listened is first established, and then multiple worker processes are forked. The listenfd of all worker processes will become readable when a new connection arrives. To ensure that only one process handles the connection, all worker processes grab accept_mutex before registering the listenfd read event. The process that grabs the mutex registers the listenfd read event. Call accept in the read event to accept the connection.

After a worker process accepts the connection, it starts to read the request, parse the request, process the request, generate data, and then return it to the client, and finally disconnect the connection. Such a complete request is That's it. We can see that a request is completely processed by the worker process, and is only processed in one worker process.

Multi-threading model VS multi-process model, this is a problem!

So, what are the benefits of nginx adopting this process model? Of course, there will definitely be many benefits. First of all, for each worker process, it is an independent process and does not need to be locked, so the overhead caused by locking is eliminated. At the same time, it will be much more convenient during programming and problem finding. Secondly, using independent processes will not affect each other. After one process exits, other processes are still working and the service will not be interrupted. The master process will quickly start a new worker process. Of course, if the worker process exits abnormally, there must be a bug in the program. Abnormal exit will cause all requests on the current worker to fail, but it will not affect all requests, so the risk is reduced. Of course, there are many benefits, and everyone can experience them slowly.

The above has talked a lot about the process model of nginx. Next, let’s take a look at how nginx handles events.

Someone may ask, nginx uses a multi-worker method to process requests. There is only one main thread in each worker, so the number of concurrencies that can be processed is very limited. How many workers can handle as many concurrencies? , how to achieve high concurrency? No, this is the brilliance of nginx. nginx uses an asynchronous and non-blocking method to process requests. In other words, nginx can handle thousands of requests at the same time.

Think about the common working method of apache (apache also has an asynchronous non-blocking version, but it conflicts with some of its own modules, so it is not commonly used). Each request will occupy a working thread. When When the number of concurrency reaches thousands, thousands of threads are processing requests at the same time. This is a big challenge for the operating system. The memory occupied by threads is very large, and the CPU overhead caused by thread context switching is very large. Naturally, the performance cannot be improved, and these overheads are completely meaningless. .

Synchronous blocking VS asynchronous non-blocking

Why can nginx be processed in an asynchronous non-blocking way, or what exactly is asynchronous non-blocking? Let’s go back to the starting point and look at the complete process of a request. First, the request comes, a connection is established, and then the data is received. After receiving the data, the data is sent. Specific to the bottom layer of the system, it is the read and write events. When the read and write events are not ready, they will inevitably be inoperable. If you do not call it in a non-blocking way, you will have to block the call. If the event is not ready, you can only wait. Okay, you can continue when the event is ready. Blocking calls will enter the kernel and wait, and the CPU will be used by others. For single-threaded workers, it is obviously not suitable. When there are more network events, everyone is waiting, and no one uses the CPU when it is idle. CPU utilization Naturally, the rate cannot go up, let alone high concurrency.

Okay, you said adding the number of processes, what is the difference between this and Apache's thread model? Be careful not to increase unnecessary context switching. Therefore, in nginx, blocking system calls are the most taboo. Don't block, then it's non-blocking. Non-blocking means that if the event is not ready, it will return to EAGAIN immediately to tell you that the event is not ready yet. Why are you panicking? Come back later. Okay, after a while, check the event again until the event is ready. During this period, you can do other things first, and then check whether the event is ready. Although it is no longer blocked, you have to check the status of the event from time to time. You can do more things, but the overhead is not small. Therefore, there is an asynchronous non-blocking event processing mechanism, and the specific system calls are system calls like select/poll/epoll/kqueue.

They provide a mechanism that allows you to monitor multiple events at the same time. Calling them is blocking, but you can set a timeout. Within the timeout, if an event is ready, it will return. This mechanism just solves our two problems above. Take epoll as an example (in the following examples, we often use epoll as an example to represent this type of function). When the event is not ready, it is placed in epoll. , when the event is ready, we go to read and write. When the read and write returns EAGAIN, we add it to epoll again. In this way, as long as an event is ready, we will process it, and only when all events are not ready, we will wait in epoll. In this way, we can handle a large number of concurrent requests. Of course, the concurrent requests here refer to unprocessed requests. There is only one thread, so of course there is only one request that can be processed at the same time. We just continuously switch between requests. That's it, the switch was voluntarily given up because the asynchronous event was not ready. There is no cost to switching here. You can understand it as processing multiple prepared events in a loop, which is actually the case.

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. class. No matter how many concurrencies there are, it will not lead to unnecessary waste of resources (context switching). More concurrency will just take up more memory. I have tested the number of connections before. On a machine with 24G memory, the number of concurrent requests processed has exceeded 2 million. Today's network servers basically use this method, which is also the main reason why nginx has high performance.

We have said before that it is recommended to set the number of workers to the number of CPU cores. It is easy to understand here. More workers will only cause processes to compete for CPU resources, thus causing unnecessary Context switch.

Moreover, nginx provides a cpu affinity binding option in order to make better use of multi-core features. We can bind a certain process to a certain core, so that there will be no problems due to process switching. Come cache failure. Small optimizations like this are very common in nginx, and it also illustrates the painstaking efforts of the nginx author. For example, when nginx compares 4-byte strings, it will convert the 4 characters into an int type and then compare them to reduce the number of CPU instructions and so on.

Now, we know why nginx chooses such a process model and event model. For a basic web server, there are usually three types of events, network events, signals, and timers. From the above explanation, we know that network events can be solved well through asynchronous non-blocking. How to deal with signals and timers?

First, signal processing.

For nginx, there are some specific signals that represent specific meanings. The signal will interrupt the current running of the program and continue execution after changing the state. If it is a system call, it may cause the system call to fail and require reentry. Regarding signal processing, you can study some professional books, so I won’t go into details here. For nginx, if nginx is waiting for an event (during epoll_wait), if the program receives a signal, after the signal processing function is processed, epoll_wait will return an error, and then the program can enter the epoll_wait call again.

In addition, let’s take a look at the timer. Since epoll_wait and other functions can set a timeout when they are called, nginx uses this timeout to implement the timer. The timer events in nginx are placed in a red-black tree that maintains timers. Each time before entering epoll_wait, the minimum time of all timer events is obtained from the red-black tree, and the timeout of epoll_wait is calculated. Enter epoll_wait after time.

So, when no event is generated and there is no interrupt signal, epoll_wait will time out, that is, the timer event has arrived. At this time, nginx will check all timeout events, set their status to timeout, and then handle the network event. It can be seen from this that when we write nginx code, the first thing we usually do when processing the callback function of a network event is to determine the timeout, and then process the network event.

For more Nginx related knowledge, visit the Nginx usage tutorial column!

The above is the detailed content of Why is nginx performance good?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Nginx Performance Tuning: Optimizing for Speed and Low Latency Nginx Performance Tuning: Optimizing for Speed and Low Latency Apr 05, 2025 am 12:08 AM

Nginx performance tuning can be achieved by adjusting the number of worker processes, connection pool size, enabling Gzip compression and HTTP/2 protocols, and using cache and load balancing. 1. Adjust the number of worker processes and connection pool size: worker_processesauto; events{worker_connections1024;}. 2. Enable Gzip compression and HTTP/2 protocol: http{gzipon;server{listen443sslhttp2;}}. 3. Use cache optimization: http{proxy_cache_path/path/to/cachelevels=1:2k

Advanced Nginx Configuration: Mastering Server Blocks & Reverse Proxy Advanced Nginx Configuration: Mastering Server Blocks & Reverse Proxy Apr 06, 2025 am 12:05 AM

The advanced configuration of Nginx can be implemented through server blocks and reverse proxy: 1. Server blocks allow multiple websites to be run in one instance, each block is configured independently. 2. The reverse proxy forwards the request to the backend server to realize load balancing and cache acceleration.

Nginx Load Balancing: Configuring for High Availability and Scalability Nginx Load Balancing: Configuring for High Availability and Scalability Apr 03, 2025 am 12:12 AM

Nginx can achieve high availability and scalability by configuring load balancing. 1) Define upstream server groups, 2) Select appropriate load balancing algorithms such as polling, weighted polling, minimum connection or IP hashing, 3) Optimize configuration and monitor and adjust server weights to ensure optimal performance and stability.

How to check whether nginx is started How to check whether nginx is started Apr 14, 2025 pm 01:03 PM

How to confirm whether Nginx is started: 1. Use the command line: systemctl status nginx (Linux/Unix), netstat -ano | findstr 80 (Windows); 2. Check whether port 80 is open; 3. Check the Nginx startup message in the system log; 4. Use third-party tools, such as Nagios, Zabbix, and Icinga.

How to configure cloud server domain name in nginx How to configure cloud server domain name in nginx Apr 14, 2025 pm 12:18 PM

How to configure an Nginx domain name on a cloud server: Create an A record pointing to the public IP address of the cloud server. Add virtual host blocks in the Nginx configuration file, specifying the listening port, domain name, and website root directory. Restart Nginx to apply the changes. Access the domain name test configuration. Other notes: Install the SSL certificate to enable HTTPS, ensure that the firewall allows port 80 traffic, and wait for DNS resolution to take effect.

How to check nginx version How to check nginx version Apr 14, 2025 am 11:57 AM

The methods that can query the Nginx version are: use the nginx -v command; view the version directive in the nginx.conf file; open the Nginx error page and view the page title.

How to start nginx server How to start nginx server Apr 14, 2025 pm 12:27 PM

Starting an Nginx server requires different steps according to different operating systems: Linux/Unix system: Install the Nginx package (for example, using apt-get or yum). Use systemctl to start an Nginx service (for example, sudo systemctl start nginx). Windows system: Download and install Windows binary files. Start Nginx using the nginx.exe executable (for example, nginx.exe -c conf\nginx.conf). No matter which operating system you use, you can access the server IP

How to check whether nginx is started? How to check whether nginx is started? Apr 14, 2025 pm 12:48 PM

In Linux, use the following command to check whether Nginx is started: systemctl status nginx judges based on the command output: If "Active: active (running)" is displayed, Nginx is started. If "Active: inactive (dead)" is displayed, Nginx is stopped.

See all articles