前言
大部分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
总结
到此这篇关于nginx有哪些常规调优手段详解的文章就介绍到这了,更多相关nginx常规调优手段内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!