nginx 全面优化 负载均衡
修改nginx.conf文件,它保存有nginx不同模块的全部设置。如果是原生安装的话应该在服务器的 /etc/nginx 目录找到 nginx.conf ,使用其它安装包的话也可以自行查找nginx.conf所在目录。
下面我以原生安装来解读nginx优化,其它安装包可参考。
顶层配置
在 nginx.conf 文件中,有一些在模块之外的顶层配置。
user www-data; pid /var/run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65535;
user 和 pid 应当使用默认值——由于它对我们的目的没有任何影响,所以我们不会修改这部分。
worker_processes 定义了 nginx 在为你的网站提供服务时,worker 进程的数量。最佳值受到包括(但不限于)CPU 核心数、存储数据的磁盘数、负载值在内的许多因素的影响。如果不确定的话,将其设置为可用的 CPU 内核的数量是一个不错的开始(设置为“auto”,将会尝试自动检测可用的值)。
worker_rlimit_nofile 修改了 worker 进程打开文件数的最大值限制。如果不设置,操作系统会限制它。当操作系统和 nginx 处理超过“ulimit -n”的数量的文件的情况时产生报告,因此将这个数值调大,这样 nginx 就不会遇到“too many open files”的问题。
# bump up our hard limit sudo sh -c ulimit -HSn 65535
为了让这个设置(在重启以后)永久生效,需要修改系统的配置文件。添加(如果已经有了,就修改)下面的行
运行vim /etc/security/limits.conf添加如下内容 * soft nofile 65535 * hard nofile 65535
然后务必重启,或者通过其他途径让 limits 生效。
events 模块
events 模块包括了 nginx 中处理链接的全部设置。
events { worker_connections 2048; multi_accept on; use epoll; }
worker_connections 设置了一个 worker 进程可以同时打开的链接数。由于已经调整了 worker_rlimit_nofile,所以可以安全的将这个数值调整得很大。记住,最大客户数也由系统的可用socket连接数限制,所以设置不切实际的高没什么好处。
multi_accept 告诉 nginx 在收到新链接的请求的通知时,尽可能接受链接。
use 设置告诉服务器由哪个线程方法来执行(轮询)。如果使用 Linux 2.6+,应当设置为 epoll。如果使用 *BSD,应当设置为 kqueue。
(需要注意的是,如果没有指定 nginx 使用哪个,它将会根据操作系统选择最合适的那个)
HTTP 模块
HTTP 模块控制了 nginx 的 http 处理的核心功能。虽然这里只有很少的设置项,但我们还是要简单的了解一下。每个配置的片段都应当放在 http 模块中,后面不再特别说明。
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
...
}
server_tokens 并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
sendfile 激活了 sendfile()。sendfile()可以在 磁盘 和 TCP端口 之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效
tcp_nopush 告诉 nginx 在一个包中发送全部的头文件,而不是一个一个发送。
tcp_nodelay 告诉 nginx 不要缓存数据,应该快速的发送小数据——这仅仅应该使用在那些频繁发送小的碎片信息而无需立刻获取响应的,需要实时传递数据的应用中。
access_log off; error_log /var/log/nginx/error.log crit;
access_log 确定了 nginx 是否保存访问日志。将这个设置为关闭可以提升硬盘IO速度(换句话说,你只有一条命)。
error_log告诉 nginx 应当记录严重道的错误。
keepalive_timeout 10; client_header_timeout 10; client_body_timeout 10; reset_timedout_connection on; send_timeout 10;
keepalive_timeout 指定了与客户端的 keep-alive 链接的超时时间。服务器会在这个时间后关闭链接。我们会降低这个值,以避免让 worker 过长时间的忙碌。
client_header_timeout和 client_body_timeout (分别)设置了请求头和请求体的超时时间。这个值也应该设置得较低。
reset_timedout_connection 告诉 nginx 当客户端失去相应时关闭链接。这将会释放为该客户端分配的所有内存。
send_timeout 指定了响应客户端的超时时间。这个时间并不是指整个传输时间,而是在客户端两次读操作之间的间隔。如果客户端在这个时间内没有准备好再次读取数据,nginx 会关闭链接。
limit_conn_zone $binary_remote_addr zone=addr:5m; limit_conn addr 100;
limit_conn_zone 设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K*5)32byte状态或者(16K*5)64byte状态
limit_conn 设置了指定key的最大连接接数。这里键为 addr,值为 100,因此将只允许每个 IP 100 个并发连接。
include /etc/nginx/mime.types; default_type text/html; charset UTF-8;
include 会直接包含其他文件的内容到当前文件。这里加载了 MIME 的列表以待使用。
default_type 设置文件默认的 MIME-type 类型。
charset 设置了头中包含的默认的字符集。
下面的两个性能改进的选项在 WebMasters StackExchange 的这个伟大问题中给予了说明。
gzip on; gzip_disable "msie6"; # gzip_static on; gzip_proxied any; gzip_min_length 512; 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 告诉 nginx gzip 压缩发送的数据。这会减少需要发送的数据的数量。
gzip_disable为指定的客户端禁用gzip功能。禁止IE6使用gzip以使我们的方案能够广泛兼容
gzip_static告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了
gzip_proxied 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。
gzip_min_length 设置了 gzip 数据的最小的字节数。由于 gzip 压缩会降低处理请求的速度,所以如果一个请求小于 1000 字节,将不对其进行压缩。
gzip_comp_level 设置了数据压缩的等级。等级可以是 1-9 的任意一个值,9 表示最慢但是最高比例的压缩。设置为 4 是一个不错的折中选择。
gzip_types 设置进行 gzip 压缩的类型。上面列了一些,你还可以自己添加更多。
# 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/*; }
open_file_cache 打开缓存并且指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。
open_file_cache_valid 指定了检查 open_file_cache 中信息的有效性的时间间隔。
open_file_cache_min_uses 定义了 open_file_cache 中在指定时间间隔里,闲置文件的最小使用次数。
open_file_cache_errors 指定了在搜索一个文件的时候是否缓存错误,
include 再次向配置添加了一些文件,如果你的服务器模块不在这些位置,你就得修改下面路径来指定正确的位置。
完整的配置文件:
user www-data; pid /var/run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65535; 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 512; gzip_comp_level 4; 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/*; }
在编辑完配置后,请确保重新加载/重启(reload/restart)nginx,以便使用新的配置文件。
sudo service nginx restart