Nginx 进阶与优化 weir 2015-08-11 14:45:30.0 nginx,分布式 2498 前面已经谈过nginx的作用了,对于一个高性能的架构来说nginx所发挥的作用就是负载均衡和反向代理,而且这也是nginx最大的优势,何乐而不为呢。所以说要发挥nginx的优势最重要的是优化配置,我想网上也应该有不少这方面的知识,优化么无非是怎么更好的利用服务器,服务器里面有什么,CPU,内存,磁盘(文件),网络对不对,对于一个高性能的服务器这些都必须考虑到最佳状态。 那么我问就一个一个来看看nginx是怎么利用这些资源的: CPU:我们都知道现在的服务器都是多核的,nginx是怎么利用的呢? worker_processes :通常配置成cpu的总核数,或者其2倍,性能会更好。 这可以减少进程间切换带来的消耗。 还可以同时使用worker_cpu_affinity来绑定cpu,使得每个worker进程独享一个cpu,实现完全的并发,性能更好,不过这个只对linux系统有效。 events里面的事件模型,Linux推荐使用epoll模型,FreeBSD推荐采用kqueue 这没什么难的,自己在网上找找资料就可以搞定,cpu嘛也可以nginx自己管理。 内存:内存是计算机不只是服务器都是非常重要的资源,原因很简单就是我们的物理磁盘才不给力了,如果磁盘能达到很高的读写速度内存的重要性也就无足轻重了,可惜呀计算机从一开始就注定了内存的伟大,地球上还没有一种物质廉价读写速度非常快还可以永久保存下来存档的物质结构?这就是一个质飞跃的问题,一旦有这种物质的出现那才真正的算是人类的革命性的进步。 worker_connections:每个进程允许的最多连接数,默认是1024,可以设置大一些。 理论上并发总数是worker_processes和worker_connections的乘积, worker_connections值的设置跟物理内存大小有关,因为系统可以打开的最大文件数和内 存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右,所以, worker_connections 的值需根据worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置。 但是往往对内存的优化都是综合的考虑。 磁盘文件:这当然是有限制的,读取一个文件要消耗内存吧,打开那就更需要内存了。 而且涉及磁盘IO的交互这是需要消耗时间的,所以说对磁盘的操作及消耗空间也消耗时间。 worker_rlimit_nofile:描述一个nginx进程打开的最多的文件数目。配置成跟linux内核下文件打开数一致就可以了。 可以通过ulimit -n 来查看,新装的系 统默认是1024,CentOS中可以如下方式进行修改: 在/etc/security/limits.conf最后增加: * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535 keepalive_timeout:设置到65左右就可以。 client_header_buffer_size:设置请求的缓存,设置为4k,通常为系统分页大小的整数倍,可以通过getconf PAGESIZE 来查看系统分页大小。 对打开文件设置缓存: open_file_cache max=建议设置成和每个进程打开的最大文件数一致inactive=60s; open_file_cache_valid 90s; open_file_cache_min_uses 2; open_file_cache_errors on; 尽量开启Gzip压缩,gzip_comp_level通常设置成3-5,高了浪费CPU。 Error日志优化:运行期间设置为crit,可以减少I/O。 日志分析可以用其他的软件代替 sendfile指令指定nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,通常应设置成on,如果是下载等应用磁盘IO重负载应用,可设置为off Buffers size优化:如果buffer size太小就会到导致nginx使用临时文件存储response,这会引起磁盘读写IO,流量越大问题越明显。 client_body_buffer_size 处理客户端请求体buffer大小。用来处理POST提交数 据,上传文件等。client_body_buffer_size 需要足够大以容纳需要上传的POST数据。同理还有后端的buffer数据。 worker_priority进程优先级设置:Linux系统中,优先级高的进程会占用更多的系统资源,这里配置的是进程的静态优先级,取值范围-20到+19,-20级别最高。因此可以把这个 值设置小一点,但不建议比内核进程的值低(通常为-5) 关于静态资源的问题也可以交给其他软件来完成,还可以利用浏览器缓存。 如果使用SSL的话,而且服务器上有SSL硬件加速设备的话,请开启硬件加速。 在前一篇文章的介绍中已经放上去了完整的配置文件,反正nginx就是玩这个配置文件的,看你怎么优化各项参数了。 这个网还算可以至少目前可以参考一下:http://tengine.taobao.org/book/index.html Nginx安装配置选项 编译参数可能会根据版本的不同进行变化,./configure --help查看编译参数列表,常见的选项如下: 1. --prefix=<path> - 安装路径,如果没有指定,默认为/usr/local/nginx。 2. --sbin-path=<path> - nginx可执行命令的文件,如果没有指定,默认为<prefix>/sbin/nginx。 3. --conf-path=<path> - 在没有使用-c参数指定的情况下nginx.conf的默认位置,如果没有指定,默认 为<prefix>/conf/nginx.conf。 4. --pid-path=<path> - nginx.pid的路径,如果没有在nginx.conf中通过“pid”指令指定,默认为 <prefix>/logs/nginx.pid。 5. --lock-path=<path> - nginx.lock文件路径,如果没有指定,默认为<prefix>/logs/nginx.lock。 6. --error-log-path=<path> - 当没有在nginx.conf中使用“error_log”指令指定时的错误日志位置, 如果没有指定,默认为<prefix>/logs/error.log。 7. --http-log-path=<path> - 当没有在nginx.conf中使用“access_log”指令指定时的访问日志位置, 如果没有指定,默认为<prefix>/logs/access.log。 8. --user=<user> -当没有在nginx.conf中使用“user”指令指定时nginx运行的用户,如果没有指定, 默认为“nobody”。 9. --group=<group> - 当没有在nginx.conf中使用“user”指令指定时nginx运行的组,如果没有指定, 默认为“nobody”。 10. --builddir=DIR - 设置构建目录。 11. --with-rtsig_module-启用rtsig模块。 --with-select_module –without-select_module-如果在configure的时候没有发现kqueue, epoll, rtsig或/dev/poll其中之一,select模块始终为启用状态。 12. --with-poll_module –without-poll_module-如果在configure的时候没有发现kqueue, epoll, rtsig或/dev/poll其中之一,poll模块始终为启用状态。 13. --with-http_ssl_module-启用ngx_http_ssl_module,启用SSL支持并且能够处理HTTPS请求。需要 OpenSSL,在Debian系统中,对应的包为libssl-dev。 14. --with-http_realip_module-启用ngx_http_realip_module 15. --with-http_addition_module-启用ngx_http_addition_module 16. --with-http_sub_module-启用ngx_http_sub_module 17. --with-http_dav_module-启用ngx_http_dav_module 18. --with-http_flv_module-启用ngx_http_flv_module 19. --with-http_stub_status_module-启用”server status”(服务状态)页 20. --without-http_charset_module-禁用ngx_http_charset_module 21. --without-http_gzip_module-禁用ngx_http_gzip_module,如果启用,需要zlib包。 22. --without-http_ssi_module-禁用ngx_http_ssi_module 23. --without-http_userid_module-禁用ngx_http_userid_module 24. --without-http_access_module-禁用ngx_http_access_module 25. --without-http_auth_basic_module-禁用ngx_http_auth_basic_module --without-http_autoindex_module-禁用ngx_http_autoindex_module 26. --without-http_geo_module-禁用ngx_http_geo_module 27. --without-http_map_module-禁用ngx_http_map_module 28. --without-http_referer_module-禁用ngx_http_referer_module 29. --without-http_rewrite_module-禁用ngx_http_rewrite_module。如果启用,需要PCRE包。 30. --without-http_proxy_module-禁用ngx_http_proxy_module 31. --without-http_fastcgi_module-禁用ngx_http_fastcgi_module 32. --without-http_memcached_module-禁用ngx_http_memcached_module 33. --without-http_limit_zone_module-禁用ngx_http_limit_zone_module 34. --without-http_empty_gif_module-禁用ngx_http_empty_gif_module 35. --without-http_browser_module-禁用ngx_http_browser_module 36. --without-http_upstream_ip_hash_module-禁用ngx_http_upstream_ip_hash_module 37. --with-http_perl_module-启用ngx_http_perl_module 38. --with-perl_modules_path=PATH - 为perl模块设置路径 39. --with-perl=PATH - 为perl库设置路径 40. --http-client-body-temp-path=PATH - 为http连接的请求实体临时文件设置路径,如果没有指定,默 认为<prefix>/client_body_temp --http-proxy-temp-path=PATH - 为http代理临时文件设置路径,如果没有指定,默认为 <prefix>/proxy_temp 41. --http-fastcgi-temp-path=PATH - 为http fastcgi临时文件设置路径,如果没有指定,默认为 <prefix>/fastcgi_temp 42. --without-http - 禁用HTTP服务 43. --with-mail - 启用IMAP4/POP3/SMTP代理模块 44. --with-mail_ssl_module-启用ngx_mail_ssl_module 45. --with-cc=PATH - 设置C编译器路径 46. --with-cpp=PATH - 设置C预处理器路径 47. --with-cc-opt=OPTIONS - 变量CFLAGS中附加的参数,用于FreeBSD中的PCRE库,同样需要指定–with-cc-opt=”-I /usr/local/include”,如果我们使用select()函数则需要同时增加文件描述符数量,可 以通过–with-cc-opt=”-D FD_SETSIZE=2048”指定。 48. --with-ld-opt=OPTIONS - 通过连接器的附加参数,用于FreeBSD中的PCRE库,同样需要指定–with-ld-opt=”-L /usr/local/lib”。 49. --with-cpu-opt=CPU - 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 50. --without-pcre-禁用PCRE库文件,同时将禁用HTTP rewrite 模块,如果要在”location”指令中使 用正则表达式,同样需要PCRE库。 --with-pcre=DIR - 设置PCRE库源文件路径。 51. --with-pcre-opt=OPTIONS - 在编译时为PCRE设置附加参数。 52. --with-md5=DIR - 设置md5库源文件路径。 53. --with-md5-opt=OPTIONS - 在编译时为md5设置附加参数。 54. --with-md5-asm - 使用md5汇编源。 55. --with-sha1=DIR - 设置sha1库源文件路径。 56. --with-sha1-opt=OPTIONS - 在编译时为sha1设置附加参数。 57. --with-sha1-asm - 使用sha1汇编源。 58. --with-zlib=DIR - 设置zlib库源文件路径。 59. --with-zlib-opt=OPTIONS - 在编译时为zlib设置附加参数。 60. --with-zlib-asm=CPU -为指定的CPU使用zlib汇编源进行优化,可用值为: pentium, pentiumpro。 61. --with-openssl=DIR - 设置openssl库源文件路径。 62. --with-openssl-opt=OPTIONS - 在编译时为openssl设置附加参数。 63. --with-debug - 启用debug记录。 64.--add-module=PATH - 增加一个在PATH中的第三方模块。 几个重要的配置文件: ##运行用户 [用户组] user root; ##nginx进程数,建议设置为等于CPU总核心数 worker_processes 1; ##全局错误日志定义类型,[ debug | info | notice | warn | error | crit ] error_log logs/error.log crit; #error_log logs/error.log notice; #error_log logs/error.log info; ##进程文件 pid logs/nginx.pid; ##一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。 worker_rlimit_nofile 1024; events { ##参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。 use epoll; ##单个进程最大连接数(最大连接数=连接数*进程数) worker_connections 1024; } ##设定http服务器 http { ##文件扩展名与文件类型映射表 include mime.types; ##反向代理配置 include ccproxy.conf; ##默认文件类型 default_type application/octet-stream; ##设置日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; ##日志输出位置 access_log logs/access.log main; ##服务器名字的hash表大小 server_names_hash_bucket_size 256; ##设置读取客户端请求正文的缓冲容量.如果请求正文大于缓冲容量,整个正文或者正文的一部分将写入临时文件。 缓冲大小默认等于两块内存页的大小,在x86平台、其他32位平台和x86-64平台,这个值是8K。在其他64位平台,这个值一般是16K。 client_body_buffer_size 128k; ##设置读取客户端请求头部的缓冲容量。 对于大多数请求,1K的缓冲足矣。 但如果请求中含有的cookie很长,或者请求来自WAP的客户端,可能请求头不能放在1K的缓冲中。 如果从请求行,或者某个请求头开始不能完整的放在这块空间中,那么nginx将按照 large_client_header_buffers指令的配置分配更多更大的缓冲来存放。 directive. client_header_buffer_size 8k; ##设置允许客户端请求正文的最大长度。请求的长度由“Content-Length”请求头指定。 如果请求的长度超过设定值,nginx将返回错误413 (Request Entity Too Large)到客户端。 请注意浏览器不能正确显示这个错误。 将size设置成0可以使nginx不检查客户端请求正文的长度。 client_max_body_size 50m; ##定义读取客户端请求头部的超时。如果客户端在这段时间内没有传送完整的头部到nginx, nginx将返回错误408 (Request Time-out)到客户端。 client_header_timeout 1m; ##定义读取客户端请求正文的超时。超时是指相邻两次读操作之间的最大时间间隔,而不是整个请求正文完成传输的最大时间。 如果客户端在这段时间内没有传输任何数据,nginx将返回408 (Request Time-out)错误到客户端。 client_body_timeout 1m; ##设置读取客户端请求超大请求的缓冲最大number(数量)和每块缓冲的size(容量)。 HTTP请求行的长度不能超过一块缓冲的容量,否则nginx返回错误414 (Request-URI Too Large)到客户端。 每个请求头的长度也不能超过一块缓冲的容量,否则nginx返回错误400 (Bad Request)到客户端。 缓冲仅在必需是才分配,默认每块的容量是8K字节。 即使nginx处理完请求后与客户端保持入长连接,nginx也会释放这些缓冲。 large_client_header_buffers 4 8k; ##设置向客户端传输响应的超时。超时仅指两次相邻写操作之间的时间间隔,而非整个响应的传输时间。 如果客户端在这段时间中没有收到任何数据,连接将关闭。 send_timeout 3m; ##开启或关闭使用sendfile()调用。 sendfile on; ##第一个参数设置客户端的长连接在服务器端保持的最长时间(在此时间客户端未发起新请求,则长连接关闭)。 第二个参数为可选项,设置“Keep-Alive: timeout=time”响应头的值。 可以为这两个参数设置不同的值。 ##“Keep-Alive: timeout=time”响应头可以被Mozilla和Konqueror浏览器识别和处理。 MSIE浏览器在大约60秒后会关闭长连接。 keepalive_timeout 120; ##开启或关闭nginx使用TCP_NODELAY选项的功能。 这个选项仅在将连接转变为长连接的时候才被启用。(译者注,在upstream发送响应到客户端时也会启用)。 tcp_nodelay on; ##开启或者关闭nginx在FreeBSD上使用TCP_NOPUSH套接字选项, 在Linux上使用TCP_CORK套接字选项。 选项仅在使用sendfile的时候才开启。 开启此选项允许 ##在Linux和FreeBSD 4.*上将响应头和正文的开始部分一起发送; ##一次性发送整个文件。 tcp_nopush on; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; upstream cctest1.com { #server 127.0.0.1:9080 weight=5; server 127.0.0.1:8080 weight=5; #server 127.0.0.1:1111; } server { listen 80; server_name ccserver1; #charset koi8-r; access_log logs/host.access.log main; index index.html index.htm index.jsp; root /root/weir/apache-tomcat-8.0.15/webapps/ROOT/; location ~* .*\.(jpg|jpeg|gif|png|swf|ico)$ { if (-f $request_filename) { #expires 15d; break; } } location ~* .*\.(html|htm|js|css)$ { #expires 1d; } ##匹配根下面的所有请求 location / { proxy_pass http://cctest1.com; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { internal; root errors/html; } } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443; # server_name localhost; # ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_timeout 5m; # ssl_protocols SSLv2 SSLv3 TLSv1; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} } types { text/html html htm shtml; text/css css; text/xml xml; image/gif gif; image/jpeg jpeg jpg; application/x-javascript js; application/atom+xml atom; application/rss+xml rss; text/mathml mml; text/plain txt; text/vnd.sun.j2me.app-descriptor jad; text/vnd.wap.wml wml; text/x-component htc; image/png png; image/tiff tif tiff; image/vnd.wap.wbmp wbmp; image/x-icon ico; image/x-jng jng; image/x-ms-bmp bmp; image/svg+xml svg svgz; image/webp webp; application/java-archive jar war ear; application/mac-binhex40 hqx; application/msword doc; application/pdf pdf; application/postscript ps eps ai; application/rtf rtf; application/vnd.ms-excel xls; application/vnd.ms-powerpoint ppt; application/vnd.wap.wmlc wmlc; application/vnd.google-earth.kml+xml kml; application/vnd.google-earth.kmz kmz; application/x-7z-compressed 7z; application/x-cocoa cco; application/x-java-archive-diff jardiff; application/x-java-jnlp-file jnlp; application/x-makeself run; application/x-perl pl pm; application/x-pilot prc pdb; application/x-rar-compressed rar; application/x-redhat-package-manager rpm; application/x-sea sea; application/x-shockwave-flash swf; application/x-stuffit sit; application/x-tcl tcl tk; application/x-x509-ca-cert der pem crt; application/x-xpinstall xpi; application/xhtml+xml xhtml; application/zip zip; application/octet-stream bin exe dll; application/octet-stream deb; application/octet-stream dmg; application/octet-stream eot; application/octet-stream iso img; application/octet-stream msi msp msm; audio/midi mid midi kar; audio/mpeg mp3; audio/ogg ogg; audio/x-m4a m4a; audio/x-realaudio ra; video/3gpp 3gpp 3gp; video/mp4 mp4; video/mpeg mpeg mpg; video/quicktime mov; video/webm webm; video/x-flv flv; video/x-m4v m4v; video/x-mng mng; video/x-ms-asf asx asf; video/x-ms-wmv wmv; video/x-msvideo avi; } #!nginx (-) # proxy.conf proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; #获取真实ip proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #获取代理者的真实ip proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 64k;