nginx有哪些常规调优手段详解
北极象 人气:0前言
大部分web应用都使用了nginx做负载均衡服务器,下面总结了nginx.conf中一些可以微调的配置。需要注意一点,这不是一个全面的微调指南。这是一个简单的预览——那些可以通过微调来提高性能设置的概述。你的情况可能不同。
nginx配置说明
nginx.conf中主要分高层配置、Events模块、HTTP 模块三个模块。下面依次介绍个模块可以微调的配置。
高层配置
user admin; #定义Nginx运行的用户 error_log ar/loginx/error.log info; #全局错误日志定义类型,[ debug | info | notice | warn | error | crit ] access_log off; #定义本虚拟主机的访问日志 pid ar/runinx.pid; #进程文件 worker_processes auto; #nginx进程数 worker_rlimit_nofile 65535; #一个nginx进程打开的最多文件描述符数目
可以微调的配置:
- worker_processes:建议设置为等于CPU总核心数。
- worker_rlimit_nofile:理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
Events模块
events { use epoll; #设置用于复用客户端线程的轮询方法,[ kqueue | rtsig | epoll | /dev/poll | select | poll ] worker_connections 65535; #单个进程最大连接数(最大连接数=连接数*进程数) multi_accept on; #开启后告诉nginx收到一个新连接通知后接受尽可能多的连接 }
可以微调的配置:
- use:如果你使用Linux 2.6+,你应该使用epoll。如果你使用BSD,你应该使用kqueue。
- worker_connections:设置可由一个worker进程同时打开的最大连接数。如果设置了上面提到的worker_rlimit_nofile,我们可以将这个值设得很高。记住,最大客户数也由系统的可用socket连接数限制(~ 64K),所以设置不切实际的高没什么好处。
HTTP 模块
HTTP模块控制着nginx http处理的所有核心特性,内容比较多,这里分批说明。
http{ server_tokens off; #开启或关闭在错误信息的“Server”响应头中输出nginx版本号 include mime.types; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型 charset utf-8; #默认编码 server_names_hash_bucket_size 128; #服务器名字的hash表大小 client_header_buffer_size 32k; #设置读取客户端请求头部的缓冲容量 large_client_header_buffers 4 64k; #设置读取客户端请求超大请求的缓冲最大number(数量)和每块缓冲的size(容量) client_max_body_size 8m; #设定请求缓存 sendfile on; #开启高效文件传输模式 autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。 tcp_nopush on; #开启或者关闭nginx在FreeBSD上使用TCP_NOPUSH套接字选项 tcp_nodelay on; #开启或关闭nginx使用TCP_NODELAY选项的功能 keepalive_timeout 120; #长连接超时时间,单位是秒 reset_timedout_connection on; #开启或关闭重置超时连接的功能 ... }
可以微调的配置:
- sendfile:指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
- tcp_nopush: 选项仅在使用sendfile的时候才开启。告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送。
- tcp_nodelay:这个选项仅在将连接转变为长连接的时候才被启用。告诉nginx不要缓存数据,而是一段一段的发送——当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。
- reset_timedout_connection:重置连接是这样执行的:关闭套接字以前,设置SO_LINGER选项的超时值为0, 那么当关闭套接字时,nginx向客户端发送TCP RST,并且释放此套接字占用的所有内存。 这样可以避免某个已关闭的套接字长时间处于FIN_WAIT1状态,并占用内存缓冲区。应该注意的事,超时的长连接仍然是正常关闭。
- client_header_buffer_size:设置读取客户端请求头部的缓冲容量。 对于大多数请求,1K的缓冲足矣。 但如果请求中含有的cookie很长,或者请求来自WAP的客户端,可能请求头不能放在1K的缓冲中。 如果从请求行,或者某个请求头开始不能完整的放在这块空间中,那么nginx将按照 large_client_header_buffers指令的配置分配更多更大的缓冲来存放。
- large_client_header_buffers:HTTP请求行的长度不能超过一块缓冲的容量,否则nginx返回错误414 (Request-URI Too Large)到客户端。 每个请求头的长度也不能超过一块缓冲的容量,否则nginx返回错误400 (Bad Request)到客户端。 缓冲仅在必需是才分配,默认每块的容量是8K字节。 即使nginx处理完请求后与客户端保持入长连接,nginx也会释放这些缓冲。
gzip模块设置
gzip on; #开启gzip压缩输出 gzip_min_length 1k; #最小压缩长度 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本 gzip_comp_level 2; #压缩等级 gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型。 limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用 upstream 127.0.0.1 { #负载均衡 server 192.168.80.121:80 weight=3; server 192.168.80.122:80 weight=2; server 192.168.80.123:80 weight=3; }
可以微调的配置:
- upstream:upstream负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
虚拟主机的配置
server{ listen 80; #监听端口 server_name www.cainiao.com cainiao.com; #域名可以有多个,用空格隔开 location / { #对 "/" 启用反向代理 proxy_pass 127.0.0.1:8080; #设置后端服务器的协议和地址 #root /home/admin/pac; #请求根目录 #index index.html index.htm; #主页 #后端的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_set_header Host $host; client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 } }
附录: nginx配置文件详解
//定义一个用户以及对应的组 user admin admin //定义nginx worker 进程的数量,设置为auto,就是默认和CPU个数一致 work_processess auto //与上面的指令协同工作。他可以让你的worker进程影响CPU内核,数字序列和work进程一样多 work_cpu_affinity auto //nginx错误日志,有debug,warn, error等五个等级 error_log /home/admin/web/logs/error.log warn //用于存放nginx守护进程的PID文件路径, 里面记录了主进程的pid号 pid /home/admin/nginx/logs/nginx-search.pid; //定义每个work进程的内核文件大小 worker_rlimit_core 1024M //定义一个worker进程可以同时处理的文件数量 worker_rlimit_nofile 100000 //与events模块一起提供的指令可以用来配置网络机制,指令参数对nginx性能产生影响 events{ //定义一个worker进程能够同时连接的数量 worker_connectins 10240; use epoll; } //该区段嵌入配置文件的根部,在该区段允许定义指令和嵌入HTTP相关模块 -http{ //隐藏nginx的版本号, 出现400 500 页面时候不会显示nginx服务器的版本号,避免漏洞 server_token off; //文件包含指令; mime.type文件里面保存了nginx的MIME类型; 里面其实也是一个types{...} include mime.type // 该指令允许你在MIME类型和文件扩展名之间建立联系, 可以补充mime.type文件没有对应关系 types{ application/x-compress .Z; application/x-gzip .gz .tgz; application/x-httpd-php .php .html; } //定义默认的MIME类型,如果文件扩展名与mime.type中类型都不匹配,就将该值写进content-type default_type text/plain; //如果该指令被启用,Nginx将使用sendFile 内核来调用文件传递。如果禁用,那么nginx将自己处理文件传递 sendfile on; //该选项只用于sendfile已启动的情况。若为on, 那么nginx将尝试单个TCP数据包中发送整个HTTP响应头 tcp_nopush on; //keep-alive能够使客户端到服务器的链接在一定时间内持续有效,在这个时间内,客户端对服务器的访问不需要再次建立链接 keepalive_timeout 0; client_header_timeout 30s; //指定持有客户端请求主体的缓存大小,如果超过这个大小,那么主体将被写到磁盘 client_body_buffer_size 32k; /**gzip是一种压缩技术。经过gzip压缩后页面大小可以变为原来的30%甚至更小**/ //开启gzip模块 off为关闭 gzip on; //识别http的协议版本 gzip_http_version 1.0; //gzip压缩比,1压缩比最小,9压缩比最大,相应的速度也会变慢 gzip_comp_level 6; // 设置允许压缩的页面最小字节数,默认为0,页面多大都压缩 gzip_min_length 1024; //启用或者禁用gzip压缩,针对代理服务器上接收到的相应体 gzip_proxied any; //有的浏览器支持压缩,有的不支持,为了避免浪费,根据HTTP头来判断是否需要压缩 gzip_vary on; gzip_disable msie6; //??? //设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流 gzip_buffers 64 8k; //匹配mime类型进行压缩,无论是否制定“text/html”类型总会被压缩 gzip_types text/xml text/plain text/css application/javascript application/x- javascript application/rss+xml; //定义文档的根目录,该目录包含你希望为访问者提供的内容 root /home/admin/web/htdocs; //定义一个默认的页面,如果请求中没有指定文件名,nginx就会使用该页面提供服务。 index index.html index.php index.htm; //proxy_set_header nginx作为反向代理服务器,将请求转发给后端真实服务器,如果不行host的重写,所有的真是服务器都会误认为是nginx服务器发送的请求。 proxy_set_header就是用于将客户端真实的host, ip信息,传送给后端服务器。 http://www.ithov.com/linux/109626_3.shtml proxy_set_header Host $host; //在这里X-Real-IP是一个自定义的变量名,名字可以随意取,在web端可以用request.getAttribute("X-Real-IP") 获取IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header Web-Server-Type nginx; // 如果需要修改从被代理服务器传来的应答头中的”Location”和”Refresh”字段,可以用指令设置。 proxy_redirect off; proxy_buffers 128 8k; proxy_intercept_errors on; //开启或者禁用404没有找到HTTP错误。例如,如果日志中充满了404错误,却由于 robots.txt文件,那么你可以将这个选项关闭掉; log_not_found off; // 用于定义发生制定的错误代码时候,使用errror_page来定义服务器的行为。最简单的形式是使用一个错误代码改变URI error_page 403 404 405 http://www.jd.com/home/error.php; error_page 500 501 502 http://www.jd.com/home/error2.php; expires_by_types modified +3y image/gif image/jpeg image/jpg text/css application/x-shockwave-flash; //限制被定义的zone的请求总数,$binary_remote_addr用于区分客户端, rate表示每秒的请求数(r/s)或者每分钟请求数(r/m) limit_req_zone $binary_remote_addr zone=one:100m rate=5r/s; #virtual servers server{ //指定用于提供web服务站点监听的套接字所使用的IIP和端口 listen 80; //在server区段指定一个或者多个主机名(hostname), Nginx接收到HTTP请求以后,会与所有server区段相比较,然后找到与客户端请求header中Host匹配的server区段。如果没有与客户端匹配的server区段,nginx会选择第一个server区段。该指令接受通配符 server_name wenda.taobao.com q.etao.com wenda.etao.com; // 定义一个日志模板用于描述访问日志中一条包含的内容,该模板由access_log指令使用 log_format eformat ' remoteaddr r e m o t e a d d r request_time_usec remoteuser[ r e m o t e u s e r [ time_local] ' '"requestmethodhttp:// r e q u e s t m e t h o d h t t p : / / hostrequesturi" r e q u e s t u r i " status $body_bytes_sent ' '" httpreferer"" h t t p r e f e r e r "" http_user_agent"'; //该指令定了访问日志文件的路径 access_log "pipe: /opt/taobao/install/cronolog/sbin/cronolog /home/admin/web/logs/search/%Y/%m/%d/access-%Y-%m-%d_%H.log" eformat; //定义文档的根目录,该目录包含你希望为访问者提供的内容 root /home/admin/web/htdocs/; //limit_req_one 同上,burst定义了最大可能的突发请求, 在一定程度上,burst定义的值就是只能同时接受最大数量的请求值 limit_req zone=one burst=5 nodelay; //set_by_lua指令支持通过一小段用户Lua代码来计算出一个结果,然后复制给Nginx 变量,和set指令相似 //Lua代码中,通过ngx.var.VARIABLE来读取Nginx的变量; 下面的一段代码是用于修复comons-fileupload-1.0版本的漏洞 set_by_lua invalid_ct 'local ct = ngx.var.http_content_type if ct and #ct >= 2049 then return 1 else return 0 end'; if ( invalid_ct 'local ct = ngx.var.http_content_type if ct and #ct >= 2049 then return 1 else return 0 end'; if ( invalid_ct = '1') { return 400; } //根据host 进行跳转的判断 if ($host = 'q.jd.com'){ //该指令允许你对当前请求的URI 进行重写,因此对客户端的请求会被重新设置 //格式为 rewrite regexp replacement 【flag】 ;; flag 包含:last, break,redirect, permanent // regexp 是URI正则表达式,他的目的是匹配后面的replacement //permanent 返回301 重定向响应,被替代的URI作为location头的值(浏览器显示跳转之后URL地址) rewrite ^/(.*) http://wenda.jd.com/ http://wenda.jd.com/1 permanent; } location ~ .(do|htm|vhtml|service|jhtml)$ { //在配置proxy_pass的时候需要注意:http://dmouse.iteye.com/blog/1880474 //符合location 样式跳转地址; 这个指令设置被代理服务器的地址和被映射的URI,地址可以使用主机名或IP加端口号的形式。 proxy_pass http://127.0.0.1:8000; //拒绝访问的IP字段 deny 113.59.*.*; } }
更多参考
更详细的模块参数请参考:http://nginx.org/cn/docs/
核心模块:http://nginx.org/cn/docs/http/ngx_http_core_module.html
总结
加载全部内容