nginx性能配置参数说明:

时间:2023-03-09 09:55:27
nginx性能配置参数说明:

nginx的配置:main配置段说明
一.正常运行的必备配置:
1、user username [groupname];
指定运行worker进程的用户和组

2、pid /path/to/pidfile_name;
指定nginxf进程的pid文件路径。

3、worker_rlimit_nofile #;
worker进程所能够打开的最大文件句柄数(最大文件描述符数量);

如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题。

4、worker_rlimit_sigpending #;

设定每个用户能够发往worker进程的信号的数量;

5、server_tokens  

并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。

二.优化性能相关的配置:
1、worker_processes #;
worker进程的个数;通常其数值应该为CPU的物理核心数量;(高版本可以使用”auto“参数)

2、worker_cpu_affinity cpumask ...;
0001  0号CPU
0010  1号CPU
0100   2号CPU
1000 3号CPU
绑定启动的worker进程到指定的CPU上,提高缓存命中率。
worker_processes 6;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000;
说明:CPU个数<进程数,服务器需要发生进程切换;nginx工作在一个进程响应多个请求的模型下,多个worker进程在没有请求的情况下工作在睡眠态,
只有有请求到达后内核调用worker进程到CPU中执行,这样就会造成上下文切换和进程会在CPU上制造缓存,执行完成后worker进程会退出CPU进入睡眠态,
缓存失效,而后来进入的worker进程会重新生成缓存,造成服务器性能降低。
可以在系统启动时将除了系统启动的其他CPU隔离出来,绑定worker进程到指定CPU上,CPU的使用权就是特定的worker进程,可以大大提高服务器性能。

3、ssl_engine device;
在存在ssl硬件加速器的服务器上,指定所使用的ssl硬件加速设备;

4、timer_resolution t;
时间解析度,值大些好,越小越精致,但是消耗大,
每次内核事件调用返回时,都会使用gettimeofday()来更新nginx缓存时钟;timer_resolution用于定义每隔多久才会由gettimeofday()更新一次缓存时钟;x86-64系统上,gettimeofday()代价已经很小,可以忽略此配置;

5、worker_priority nice;
-20,19之间的值;让worker以指定nice值工作,-20~19nice值越低就会优先获取CPU资源; ps axo comm,pid ,nice

三.事件相关的配置
1、accept_mutex [on|off]
是否打开Ningx的负载均衡锁;on能够让各个worker进轮流地、序列化地与新的客户端建立连接; off指每个新请求的到达都会通知(唤醒)所有的worker进程,但只有一个进程可以获取得连接,造成“惊群”,影响性能。

2、lock_file /path/to/lock_file;
lock文件(accept_mutex指的负载均衡锁)

3、accept_mutex_delay #ms;
accept锁模式中,一个worker进程为取得accept锁的等待时长;如果某worker进程在某次试图取得锁时失败了,至少要等待#ms才能再一次请求锁;

4、multi_accept on|off;
是否允许一次性地响应多个用户请求;默认为Off;

5、use [epoll|rtsig|select|poll];
定义使用的事件模型,建议让nginx自动选择;

6、worker_connections #;
每个worker能够并发响应最大请求数;# 并发总数是 worker_processes 和 worker_connections 的乘积  即 max_clients = worker_processes * worker_connections

# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4  为什么

    # 为什么上面反向代理要除以4,应该说是一个经验值
    # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
    # worker_connections 值的设置跟物理内存大小有关
    # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
    # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
    # 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
    # $ cat /proc/sys/fs/file-max
    # 输出 34336
    # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
    # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
    # 使得并发总数小于操作系统可以打开的最大文件数目
    # 其实质也就是根据主机的物理CPU和内存进行配置
    # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
    # ulimit -SHn 65535

四.用于调试、定位问题: 只调试nginx时使用
1、daemon on|off;
是否让ningx运行后台(守护进程的方式启动nginx);默认为on,调试时可以设置为off,使得所有信息去接输出控制台;

2、master_process on|off
是否以master/worker模式运行nginx;默认为on;调试时可设置off以方便追踪;

3、error_log /path/to/error_log level;

级别以notice,debug,info,warn,error,crit模式,debug输出最多,crir输出最少

错误日志文件及其级别;默认为error级别;调试时可以使用debug级别,但要求在编译时必须使用--with-debug启用debug功能;

 五.网络连接相关的设置:
1、keepalive_timeout time;
保持连接的超时时长;默认为75秒;
参数的第一个值指定了客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接。参数的第二个值(可选)指定了应答头中Keep-Alive: timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,
如果不指定这个参数,nginx不会在应 答头中发送Keep-Alive信息。(但这并不是指怎样将一个连接“Keep-Alive”)参数的这两个值可以不相同。

在http早期 ,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。但是,keep-alive并不是免费的午餐,长时间的tcp连接容易导致系统资源无效占用。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置keep-alive timeout时间非常重要。

2、keepalive_requests n;默认为100
在一次长连接上允许承载的最大请求数;

3、keepalive_disable [msie6 | safari | none ]
对指定的浏览器禁止使用长连接;

4、tcp_nodelay on|off
对keepalive连接是否使用TCP_NODELAY选项;默认on,不延迟发送。 off时,延迟发送,合并多个请求后再发送。
tcp_nopush on;
http请求包体的最大值;常用于限定客户所能够请求的最大包体;根据请求首部中的Content-Length来检测,以避免无用的传输;

5、client_header_timeout time;
读取http请求首部的超时时长;

指令指定读取客户端请求头标题的超时时间。这里的超时是指一个请求头没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Request time out” (408)错误。

6、client_body_timeout time;
读取http请求包体的超时时长;

指令指定读取请求实体的超时时间。这里的超时是指一个请求实体没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Request time out” (408)错误。

7、send_timeout time;
发送响应报文的超时时长;默认为60秒

指令指定了发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接。

8、reset_timeout_connection 

告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。

六.对客户端请求的限制:
1、limit_except method ... { ... }
指定对范围之外的其它方法的访问控制;

limit_except GET {
allow 172.16.0.0/16;
deny all;
}

2、client_max_body_size SIZE;
http请求包体的最大值;常用于限定客户所能够请求的最大包体;根据请求首部中的Content-Length来检测,以避免无用的传输;

3、limit_rate speed;
限制客户端每秒钟传输的字节数;默认为0,表示没有限制;

4、limit_rate_after time;
nginx向客户发送响应报文时,如果时长超出了此处指定的时长,则后续的发送过程开始限速;

4、limit_conn perip 200;

limit_conn限制每一个IP并发连接数是200;

5 、limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 
  limit_req zone=one burst=3 nodelay;

用于按key限制请求的处理速率,特别适用于限制单个IP的请求处理速率。
本例中,设置了10m字节的共享空间来存储key,即$binary_remote_addr,共享空间的名字是one,限制请求的处理速率为一秒一个。
下面limit_req中指定了burst参数为5,表示最多允许五个请求排队,超过的就直接返回503状态了。
咱们限制的请求处理速率是一秒一个,burst参数为5。意思就是在某一秒内,允许有1个正常请求+5个excessive请求被处理,多的就要被503了。
如果没有nodelay参数,那么最多burst个excessive请求则按rate参数规定的速率延迟发送给后端。
如果有nodelay参数,则表示这些excessive请求会立马发送给后端。所以这种情况下,后端请求到达的速率可能不止rate这么多。
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_req zone=one burst=3 nodelay;

测试参考地址:http://mp.weixin.qq.com/s?__biz=MzI5ODExMjk4Ng==&mid=402812915&idx=1&sn=e8fca3a91539c152398c6fb01c9dcef6&mpshare=1&scene=1&srcid=100834dW5nyrd7PKiRgnxYk2#rd

6、limit_conn_zone $binary_remote_addr zone=perip:10M 
   limit_conn perip 200;

一个是限制并发连接
要限制连接,必须先有一个容器对连接进行计数,"zone=" 给它一个名字,可以随便叫,这个名字要跟下面的 limit_conn 一致
$binary_remote_addr = 用二进制来储存客户端的地址,1m 可以储存 32000 个并发会话
limit_conn_zone $binary_remote_addr zone=perip:10M
limit_conn perip 200;

测试参考地址:http://storysky.blog.51cto.com/628458/642970/

七.文件操作的优化:
1、sendfile on|off
是否启用sendfile功能; 可以让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。

之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效

2、aio on|off
是否启用aio(异步IO模式)功能;

、directio size | off
当size大于等于时,是否启用直接IO模式功能。(直接IO模式表示不在内存中缓存)

3、open_file_cache max=N [inactive=time]|off
是否打开文件缓存功能;
max: 缓存条目的最大值;当满了以后将根据LRU算法进行置换;
inactive: 某缓存条目在指定时长时没有被访问过时,将自动被删除;默认为60s;
缓存的信息包括:
文件句柄、文件大小和上次修改时间;
已经打开的目录结构;
没有找到或没有访问权限的信息;

4、open_file_cache_errors on|off
是否缓存文件找不到或没有权限访问等相关信息;

5、open_file_cache_valid time;
多长时间检查一次缓存中的条目是否超出非活动时长,默认为60s;

6、open_file_cache_min_use #;
在inactive指定的时长内被访问超此处指定的次数地,才不会被删除;

八.对客户端请求的特殊处理:
1、ignore_invalid_headers on|off
是否忽略不合法的http首部;默认为on; off意味着请求首部中出现不合规的首部将拒绝响应;只能用于server和http;

2、log_not_found on|off
是否将文件找不到的信息也记录进错误日志中;

3、resolver address;
指定nginx使用的dns服务器地址;

4、resover_timeout time;
指定DNS解析超时时长,默认为30s;

5、server_tokens on|off;
是否在错误页面中显示nginx的版本号;

九.nginx代理设置优化:

proxy_pass http://127.0.0.1:8080;   #来自jsp请求交给tomcat处理

proxy_redirect off;

proxy_set_header Host $host;    #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 90;   #nginx跟后端服务器连接超时时间(代理连接超时)

proxy_read_timeout 90;      #连接成功后,后端服务器响应时间(代理接收超时)

proxy_buffer_size 4k;       #设置代理服务器(nginx)保存用户头信息的缓冲区大小

proxy_buffers 6 32k;        #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置

proxy_busy_buffers_size 64k;#高负荷下缓冲大小(proxy_buffers*2)

proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传

十.内存及磁盘资源分配:
1、client_body_in_file_only on|clean|off
HTTP的包体是否存储在磁盘文件中;非off表示存储,即使包体大小为0也会创建一个磁盘文件;on表示请求结束后包体文件不会被删除,clean表示会被删除;

2、client_body_in_single_buffer on|off;
HTTP的包体是否存储在内存buffer当中;默认为off;

3、cleint_body_buffer_size size;默认为16K
nginx接收HTTP包体的内存缓冲区大小;(超出将存储到硬盘上。使用client_body_temp_path)

这个指令可以指定连接请求实体的缓冲区大小。如果连接请求超过缓存区指定的值,那么这些请求实体的整体或部分将尝试写入一个临时文件。

4、client_body_temp_path dir-path [level1 [level2 [level3]]];
HTTP包体存放的临时目录;
client_body_temp_path /var/tmp/client/ 1 2

5、client_header_buffer_size size;
正常情况下接收用户请求的http报文header部分时分配的buffer大小;默认为1k;

指令指定客户端请求头部的缓冲区大小。绝大多数情况下一个请求头不会大于1k,不过如果有来自于wap客户端的较大的cookie它可能会大于 1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers里面设置。

6、large_client_header_buffers number size;
存储超大Http请求首部的内存buffer大小及个数;

指定客户端一些比较大的请求头使用的缓冲区数量和大小。请求字段不能大于一个缓冲区大小,如果客户端发送一个比较大的头,nginx将返回”Request URI too large” (414)同样,请求的头部最长字段不能大于一个缓冲区,否则服务器将返回”Bad request” (400)。
缓冲区只在需求时分开。默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,如果一个连接请求最终将状态转换为keep- alive,它所占用的缓冲区将被释放。

6、client_max_body_size 200M;

http请求包体的最大值;常用于限定客户所能够请求的最大包体;根据请求首部中的Content-Length来检测,以避免无用的传输;
指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段。如果请求大于指定的值,客户端将收到一个”Request Entity Too Large” (413)错误。记住,浏览器并不知道怎样显示这个错误。

7、connection_pool_size size;
nginx对于每个建立成功的tcp连接都会预先分配一个内存池,此处即用于设定此内存池的初始大小;默认为256;

8、request_pool_size size;
nginx在处理每个http请求时会预先分配一个内存池,此处即用于设定此内存池的初始大小;默认为4k;

十一  压缩说明

gzip 是告诉nginx采用gzip压缩的形式发送数据。这将会减少我们发送的数据量。

gzip_disable 为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容。

gzip_http_version 1.1;

gzip_static 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了

gzip_min_length 设置对数据启用压缩的最少字节数。如果一个请求小于1000字节,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度。

gzip_comp_level 设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。我们设置为4,这是一个比较折中的设置。(压缩级别,1压缩比最小处理速度最快,9压缩比最大但处理最慢,同时也最消耗CPU,一般设置为3就可以了)

gzip_buffers     4 8k; (设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流)

gzip_type 设置需要压缩的数据格式。上面例子中已经有一些了,你也可以再添加更多的格式。 text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

gzip_proxied 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] …

Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含”Via”的 header头。

  off – 关闭所有的代理结果数据的压缩
  expired – 启用压缩,如果header头中包含 “Expires” 头信息
  no-cache – 启用压缩,如果header头中包含 “Cache-Control:no-cache” 头信息
  no-store – 启用压缩,如果header头中包含 “Cache-Control:no-store” 头信息
  private – 启用压缩,如果header头中包含 “Cache-Control:private” 头信息
  no_last_modified – 启用压缩,如果header头中不包含 “Last-Modified” 头信息
  no_etag – 启用压缩 ,如果header头中不包含 “ETag” 头信息
  auth – 启用压缩 , 如果header头中包含 “Authorization” 头信息
  any – 无条件启用压缩

十二 locaton 匹配说明

1、利用valid_referers指令防盗链:

HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,

例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链

情况。

none:表示无Referer值的情况。
blocked:表示Referer值被防火墙进行伪装。
server_names:表示一个或多个主机名称。从Nginx 0.5.33版本开始,server_names中可以使用通配符"*"号。

location ~* \.(gif|jpg|png|swf|flv|css|js|flv|swf|jpeg)$ {
valid_referers none blocked *.zjol.com.cn *.zzhz.com.cn *.zjtdw.com;    定义合规的引用
if ($invalid_referer) {     return 403; }  拒绝不合规的引用

2、nginxphp-fpm一样内建了一个状态页,对于想了解nginx的状态以及监控nginx非常有帮助。查看http://127.0.0.1/ngx_status

active connections – 活跃的连接数量
server accepts handled requests — 总共处理了多少个连接 , 成功创建多少次握手, 总共处理了多少个请求
reading — 读取客户端的连接数.
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.

location ~ ^/NginxStatus/{
stub_status on;
access_log off;

allow 127.0.0.1;

}

3、ginx.conf 配置中有个漏洞,那就是没有配置哪些目录是不允许直接访问的,在传统tomcat作为服务器的时候,tomcat本身的机制就禁止直接访问WEB-INF下的内容,

但是在nginx中,由于配置了部分内容直接从nginx转发出去,这就导致了WEB-INF目录实际上可能会被暴露出去,一旦暴漏了,那么系统架构,源代码,数据库配置文件,

系统配置文件等内容将一并泄露,这对于商业项目来讲会是致命的安全隐患,再次提醒自己以及相关人士,一定要配置不允许访问的目录。
location ~ ^/(WEB-INF|META-INF)/{
deny all;
}

4、封杀特定的url特定的文件扩展名,比如.bak

location ~* \.(bak|save|sh|sql|mdb|svn|git|old|php|zip|exe|rar|asp|aspx)$ {
return 405;
}

5、
location ~ /\.ht {
deny all;
}

5、你可以对指定的目录设置访问权限。所有的网站目录应该一一的配置,只允许必须的目录访问权限。你可以通过IP地址来限制访问目录/docs/:

location /docs/ {

deny    192.168.1.1;

allow   192.168.1.0/24;}

十三  其它安全加固说明

1、封杀各种user-agent,user-agent 也即浏览器标识,每个正常的web请求都包含用户的浏览器信息,除非经过伪装,恶意扫描工具一般都会在user-agent里留下某些特征字眼,

比如scan,nmap等。我们可以用正则匹配这些字眼,从而达到过滤的目的

if ($http_user_agent ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan" ) {
return 403;
}

if ($http_user_agent ~* "" ) {      return 403;  }

阻止Soso和有道的机器人:

if ($http_user_agent ~* Sosospider|YodaoBot) {return 403;

2、封杀特定的http方法和行为

if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 405;
}
if ($http_range ~ "\d{9,}") {
return 444;
}

3、强制网站使用域名访问,可以逃过IP扫描,
if ( $host !~* 'abc.com' ) { return 403;}

4、强制要求referer

if ($http_referer = "" ) {   return 403;  }