Nginx configuration optimization details

  • 2020-05-06 12:16:25
  • OfStack

Most Nginx installation guides tell you the basics - by installing apt-get, modifying a few lines of configuration here and there, you've got an Web server! Also, in most cases, a regular installation of nginx will work fine for your site. However, if you really want to squeeze out nginx's performance, you have to go deeper. In this guide, I'll explain that the Settings for Nginx can be fine-tuned to optimize performance when handling a large number of clients. It is important to note that this is not a comprehensive fine-tuning guide. This is a simple preview - an overview of those Settings that can be tweaked to improve performance. Your situation may be different.

basic (optimized) configuration

The only file we will modify is nginx.conf, which contains all the Settings for the different modules of Nginx. You should be able to find nginx.conf in the server's /etc/nginx directory. First, we'll talk about some global Settings, and then, one by one, the modules in the file, talk about which Settings give you good performance with lots of client access, and why they improve performance. There is a complete configuration file at the end of this article.

high level configuration

In the nginx.conf file, Nginx has a few advanced configurations on top of the module section.


user www-data;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;

user and pid should be set by default - we won't change this because it doesn't make any difference whether we change or not.
worker_processes defines the number of worder processes when nginx provides web services to outsiders. The optimal value depends on a number of factors, including (but not limited to) the number of CPU cores, the number of hard disks to store the data, and the load pattern. When in doubt, setting it to the number of CPU kernels available is a good start (setting it to "auto" will try to detect it automatically).
worker_rlimit_nofile changes the maximum open file limit for the worker process. If not set, this value is the operating system limit. Your operating system and Nginx can handle more files than "ulimit-a", so set this value higher so that nginx doesn't have "too many open files" problems.


Events module

The events module contains all the Settings for handling connections in nginx.


events {
    worker_connections 2048;
    multi_accept on;
    use epoll;
}

worker_connections sets the maximum number of connections that can be opened simultaneously by an worker process. If we set worker_rlimit_nofile as mentioned above, we can set this value very high.
Remember that the maximum number of customers is also limited by the number of connections available on the system (~ 64K), so there is no benefit in setting an unrealistically high number.

multi _accept tells nginx to accept as many connections as possible upon receipt of a new connection notification.

use sets the polling method used to reuse client threads. If you use Linux 2.6+, you should use epoll. If you use *BSD, you should use kqueue. Want to know more about event polling? Take a look at wikipedia (note that to understand everything you may need neckbeard and the basics of operating systems)

(note that if you don't know which polling method Nginx will use, it will choose the one that works best for your operating system.

HTTP module

The HTTP module controls all the core features handled by nginx http. Since there is very little configuration here, we will only excerpt a small portion of the configuration. All of these Settings should be in the http module, and you won't even notice them specifically.


http {
    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    ...
}

server_tokens does not make nginx execute faster, but it can close the nginx version number in the error page, which is good for security.
sendfile makes sendfile() work. sendfile() can copy data between disk and TCP socket (or any two file descriptors). Pre-sendfile is an application for a data buffer in user space before transferring data. Then copy the data from the file to this buffer with read(), and write() writes the buffer data to the network. sendfile() immediately reads data from disk to OS cache. Because this copy is done in the kernel, sendfile() is more efficient than combining read() and write() and turning on and off the discard buffer (more on sendfile)

tcp_nopush tells nginx to send all the header files in a single packet instead of sending
one by one tcp_nodelay tells nginx not to cache the data, but to send it paragraph by paragraph -- when the data needs to be sent in a timely manner, this property should be set for the application, so that when a small piece of data is sent, the return value is not immediately available.


access_log off;
error_log /var/log/nginx/error.log crit;

access_log sets whether nginx will store access logs. Turning this option off makes the read disk IO operation faster (aka,YOLO)
error_log tells nginx that only serious errors can be recorded


keepalive_timeout 10;
client_header_timeout 10;
client_body_timeout 10;
reset_timedout_connection on;
send_timeout 10;

keepalive_timeout assigns keep-alive link timeout to the client. The server closes the link after this timeout. We set it lower to keep ngnix working longer.
client_header_timeout and client_body_timeout set the timeout time for the request header and body (respectively). We can also set this a little bit lower.

reset_timeout_connection tells nginx to close a non-responsive client connection. This will free up the memory space occupied by that client.
send_timeout specifies the client's response timeout. This setting is not used for the entire transponder, but between two client read operations. If the client does not read any data during this time, nginx closes the connection.


limit_conn_zone $binary_remote_addr zone=addr:5m;
limit_conn addr 100;

limit_conn_zone sets the parameters used to hold the various key Shared memory, such as the current number of connections. 5m is 5 megabytes. This value should be set large enough to store (32K*5) 32byte state or (16K*5) 64byte state.
limit_conn sets the maximum number of connections for a given key. Here key is addr, and we set the value to 100, which means that we allow each IP address to have at most 100 connections open at the same time.


include /etc/nginx/mime.types;
default_type text/html;
charset UTF-8;

include is simply an instruction that contains the contents of another file in the current file. Here we use it to load a series of MIME types that we will use later.
default_type Settings file USES the default MIME-type.
charset sets the default character set

in our header file

The following two points explain the performance improvements in the great WebMasters StackExchange.


gzip on;
gzip_disable "msie6";
# gzip_static on;
gzip_proxied any;
gzip_min_length 1000;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

gzip tells nginx to send data in the form of gzip compression. This will reduce the amount of data we send.
gzip_disable disables gzip for the specified client. We set up IE6 or lower to make our solution widely compatible.
gzip_static tells nginx to look for any preprocessed resources before compressing them. This requires you to pre-compress your files (commented out in this example), which allows you to use the maximum compression ratio so that nginx doesn't have to compress them anymore (for more information on gzip_static, click here).
gzip_proxied allows or disallows compression of response streams based on requests and responses. We set it to any, which means that all requests will be compressed.
gzip_min_length sets the minimum number of bytes of data to enable compression. If a request is less than 1000 bytes, we'd better not compress it, because compressing this small amount of data slows down all the processes that process the request.
gzip_comp_level sets the compression level of the data. This level can be anything between 1 and 9, which is the slowest but has the largest compression ratio. We're going to set it to 4, which is a compromise.
gzip_type sets the format of the data to be compressed. There are already some in the above example, you can also add more formats.



# cache informations about file descriptors, frequently accessed files
# can boost performance, but you need to test those values
open_file_cache max=100000 inactive=20s; 
open_file_cache_valid 30s; 
open_file_cache_min_uses 2;
open_file_cache_errors on;
##
# Virtual Host Configs
# aka our settings for specific servers
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

When open_file_cache opens the cache, it also specifies the maximum number of caches and the cache time. We can set a relatively high maximum time so that we can clear them after they are inactive for more than 20 seconds.
open_file_cache_valid specifies the interval to detect the correct information in open_file_cache.
open_file_cache_min_uses defines the minimum number of files in open_file_cache during the inactivity time of the instruction parameter.
open_file_cache_errors specifies whether to cache error information when searching a file, including adding a file to the configuration again. We also include server modules, which are defined in different files. If your server module is not in these locations, you will have to modify this line to specify the correct location.

A complete

configuration


user www-data;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
    worker_connections 2048;
    multi_accept on;
    use epoll;
}
http {
    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    access_log off;
    error_log /var/log/nginx/error.log crit;
    keepalive_timeout 10;
    client_header_timeout 10;
    client_body_timeout 10;
    reset_timedout_connection on;
    send_timeout 10;
    limit_conn_zone $binary_remote_addr zone=addr:5m;
    limit_conn addr 100;
    include /etc/nginx/mime.types;
    default_type text/html;
    charset UTF-8;
    gzip on;
    gzip_disable "msie6";
    gzip_proxied any;
    gzip_min_length 1000;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    open_file_cache max=100000 inactive=20s; 
    open_file_cache_valid 30s; 
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

After editing the configuration, be sure to restart nginx for the Settings to take effect.


events {
    worker_connections 2048;
    multi_accept on;
    use epoll;
}
0


Related articles: