• 1. Nginx详解——介绍、模块、运维 薛长俊 2013.8
  • 2. 目 录介绍模块运维
  • 3. 目 录介绍模块运维
  • 4. 基本HTTP特性处理静态文件,索引文件以及自动索引; 打开文件描述符缓存; 使用缓存加速反向代理; 简单负载均衡以及容错; 远程FastCGI,uwsgi,SCGI,和memcached服务的缓存加速支持; 模块化的架构。过滤器包括gzip压缩、ranges支持、chunked响应、XSLT,SSI以及图像缩放。在SSI 过滤器中,一个包含多个SSI的页面,如果经由FastCGI或反向代理处理,可被并行处理; 支持SSL,TLS SNI。
  • 5. 其他HTTP特性基于名字和IP的虚拟主机; Keep-alive和pipelined连接支持; 灵活的配置; 重新加载配置以及在线升级时,不需要中断正在处理的请求; 自定义访问日志格式,带缓存的日志写操作以及快速日志轮转; 3xx-5xx错误代码重定向; 重写(rewrite)模块:使用正则表达式改变URI; 根据客户端地址执行不同的功能; 基于客户端IP地址和HTTP基本认证机制的访问控制; 支持验证HTTP referer; 支持PUT、DELETE、MKCOL、COPY以及MOVE方法; 支持FLV流和MP4流; 速度限制; 来自同一地址的同时连接数或请求数限制; 嵌入Perl语言。
  • 6. 邮件代理服务器特性使用外部HTTP认证服务器重定向用户到IMAP/POP3后端; 使用外部HTTP认证服务器认证用户后重定向连接到内部SMTP后端; 支持的认证方式: POP3: USER/PASS, APOP, AUTH LOGIN/PLAIN/CRAM-MD5; IMAP: LOGIN, AUTH LOGIN/PLAIN/CRAM-MD5; SMTP: AUTH LOGIN/PLAIN/CRAM-MD5; SSL支持; STARTTLS和STLS支持。
  • 7. 架构和可扩展性一个主进程和多个工作进程,工作进程以非特权用户运行; 支持的事件机制:kqueue(FreeBSD 4.1+)、epoll(Linux 2.6+)、rt signals(Linux 2.2.19+)、/dev/poll(Solaris 7 11/99+)、event ports(Solaris 10)、select以及poll; 众多支持的kqueue特性包括EV_CLEAR、EV_DISABLE(临时禁止事件)、NOTE_LOWAT、EV_EOF,可用数据的数量,错误代码; 支持sendfile(FreeBSD 3.1+, Linux 2.2+, Mac OS X 10.5+)、sendfile64(Linux 2.4.21+)和sendfilev(Solaris 8 7/01+); 文件AIO(FreeBSD 4.3+, Linux 2.6.22+); DIRECTIO (FreeBSD 4.4+, Linux 2.4+, Solaris 2.6+, Mac OS X); 支持Accept-filters(FreeBSD 4.1+, NetBSD 5.0+)和 TCP_DEFER_ACCEPT(Linux 2.4+); 10000个非活跃的HTTP keep-alive连接仅占用约2.5M内存; 尽可能避免数据拷贝操作。
  • 8. 测试过的系统和平台 FreeBSD 3 — 10 / i386; FreeBSD 5 — 10 / amd64; Linux 2.2 — 3 / i386; Linux 2.6 — 3 / amd64; Solaris 9 / i386, sun4u; Solaris 10 / i386, amd64, sun4v; AIX 7.1 / powerpc; HP-UX 11.31 / ia64; MacOS X / ppc, i386; Windows XP, Windows Server 2003.
  • 9. 目 录介绍模块运维
  • 10. 内核模块配置示例 user nobody; worker_processes 4; #error_log /opt/nginx_logs/error.log; #error_log /opt/nginx_logs/error.log notice; #error_log /opt/nginx_logs/error.log info; pid logs/nginx.pid; worker_rlimit_nofile 65535;
  • 11. 内核模块 设置工作的进程数(可设置为可用cpu的数量)。 语法: worker_processes number 默认值: 1 上下文: main 指定错误日志的文件和错误级别。 语法: error_log file [ debug | info | notice | warn | error | crit ] 默认值: ${prefix}/logs/error.log 上下文: http,server,location 定义一个worker进程可以同时处理的文件数量。 语法: worker_rlimit_nofile limit 默认值: OS默认 上下文: main
  • 12. 事件模块配置示例。 events { use epoll; worker_connections 65535; } 指定事件响应模式。 语法: use type 默认值: 在编译时指定 上下文: events 设置每个worker进程所能处理的连接数。 语法: worker_connections number 默认值: 1024 上下文: events
  • 13. HTTP内核模块 配置范例 http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip off; upstream backup { server127.0.0.1:8010; server127.0.0.1:8011; keepalive10; }
  • 14. HTTP内核模块 server { listen 192.168.1.1:80; server_nameexample.comwww.example.com; if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } location / { [configurationA] }
  • 15. HTTP内核模块 location ^~ /images/ { if ($request_method = POST) { proxy_pass http://backup; } [configurationB] } location ~ /purge(/.*) { allow 127.0.0.1; deny all; } } }
  • 16. HTTP内核模块为HTTP服务器提供配置上下文。 语法: http { ... } 默认值: — 上下文: main 开始设置虚拟主机。 语法: server { ... } 默认值: — 上下文: http 为某个请求URI(路径)建立配置。 语法: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } 默认值: — 上下文: server, location
  • 17. HTTP内核模块计算指定的condition的值。 语法: if (condition) { ... } 默认值: — 上下文: server, location 停止处理当前这一轮的rewrite指令集。 语法: break; 默认值: — 上下文: server, location, if 停止处理并返回指定code给客户端。 语法: return code [text]; return code URL; return URL; 默认值: — 上下文: server, location, if
  • 18. HTTP内核模块匹配条件 变量名;如果变量值为空或者是以“0”开始的字符串,则条件为假; 使用“=”和“!=”运算符比较变量和字符串; 使用“~”(大小写敏感)和“~*”(大小写不敏感)运算符匹配变量和正则表达式。正则表达式可以包含匹配组,匹配结果后续可以使用变量$1..$9引用。如果正则表达式中包含字符“}”或者“;”,整个表达式应该被包含在单引号或双引号的引用中。 使用“-f”和“!-f”运算符检查文件是否存在; 使用“-d”和“!-d”运算符检查目录是否存在; 使用“-e”和“!-e”运算符检查文件、目录或符号链接是否存在; 使用“-x”和“!-x”运算符检查可执行文件; 正则 正则匹配.xlsx
  • 19. HTTP内核模块定义将要被作为默认页的文件。 语法: index file ...; 默认值: index index.html; 上下文: http, server, location 为请求设置根目录 。 语法: root path; 默认值: root html; 上下文: http, server, location, if in location 定义指定路径的替换路径。 语法: alias path; 默认值: — 上下文: location
  • 20. HTTP内核模块设置虚拟主机名。 语法: server_name name ...; 默认值: server_name ""; 上下文: server 设置客户端的长连接在服务器端保持的最长时间。 语法: keepalive_timeout timeout [header_timeout]; 默认值: keepalive_timeout 75s; 上下文: http, server, location 为指令错误定义显示的URI 。 语法: error_page code ... [=[response]] uri; 默认值: — 上下文: http, server, location, if in location
  • 21. HTTP内核模块内嵌变量 $arg_name,请求行中的name参数。 $args,请求行中参数字符串。 $binary_remote_addr,客户端IP地址的二进制形式,长度总是4字节。 $body_bytes_sent,nginx返回给客户端的字节数,不含响应头。 $bytes_sent,nginx返回给客户端的字节数(1.3.8, 1.2.5)。 $connection,连接的序列号(1.3.8, 1.2.5)。 $content_length,“Content-Length”请求头的值。 $content_type,“Content-Type”请求头的值。 $cookie_name,名为name的cookie。 $document_root,当前请求的root指令或alias指令的配置值。 $document_uri,与$uri相同。 $host,“Host”请求头的值,如果没有该请求头,则为与请求对应的虚拟主机的首要主机名。
  • 22. HTTP内核模块$hostname,机器名称。 $http_name,任意请求头的值;变量名的后半部为转化为小写并且用下划线替代横线后的请求头名称。 $https,如果连接是SSL模块,返回“on”,否则返回空字符串。 $is_args,如果请求行带有参数,返回“?”,否则返回空字符串。 $limit_rate,允许设置此值来限制连接的传输速率。 $msec,当前时间,单位是秒,精度是毫秒。(1.3.9, 1.2.6) $nginx_version,nginx版本号。 $pid,worker进程的PID。 $query_string,与$args相同。 $realpath_root,按root指令或alias指令算出的当前请求的绝对路径。其中的符号链接都会解析成真是文件路径。 $remote_addr,客户端IP地址。 $remote_port,客户端端口。 $remote_user,为基本用户认证提供的用户名。
  • 23. HTTP内核模块$request,完整的原始请求行。 $request_body,请求正文。在由proxy_pass指令和 fastcgi_pass指令处理的路径中, 这个变量值可用。 $request_body_file,请求正文的临时文件名。处理完成时,临时文件将被删除。 如果希望总是将请求正文写入文件,需要开启client_body_in_file_only。 如果在被代理的请求或FastCGI请求中传递临时文件名,就应该禁止传递请求正文本身。 使用proxy_pass_request_body off指令 和fastcgi_pass_request_body off指令 分别禁止在代理和FastCGI中传递请求正文。 $request_completion,请求完成时返回“OK”,否则返回空字符串。 $request_filename,基于root指令或alias指令,以及请求URI,得到的当前请求的文件路径。 $request_method,HTTP方法,通常为“GET”或者“POST”。 $request_time,请求处理的时间,单位为秒,精度是毫秒(1.3.9, 1.2.6);请求处理时间从由客户端接收到第一个字节开始计算。 $request_uri,完整的原始请求行(带参数)。
  • 24. HTTP内核模块$scheme,请求协议类型,为“http”或“https”。 $sent_http_name,任意的响应头字段的值。 变量名的后半部为转化为小写并且用下划线替代横线后的响应头名称。 $server_addr,接受请求的服务器地址。为计算这个值,通常需要进行一次系统调用。为了避免系统调用,必须指定listen指令 的地址,并且使用bind参数。 $server_name,接受请求的虚拟主机的首要主机名。 $server_port,接受请求的虚拟主机的端口。 $server_protocol,请求协议,通常为“HTTP/1.0”或“HTTP/1.1”。 $status,响应状态码。 $tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space,客户端TCP连接的信息,在支持套接字选项TCP_INFO的系统中可用。 $uri,当前请求规范化以后的URI。变量$uri的值可能随请求的处理过程而改变。 比如,当进行内部跳转时,或者使用默认页文件。
  • 25. Log模块配置实例 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" "$gzip_ratio"'; access_log /spool/logs/nginx-access.log main buffer=32k; 为访问日志设置路径,格式和缓冲区大小。 语法: access_log path [format [buffer=size]]; access_log off; 默认值: access_log logs/access.log combined; 上下文: http, server, location, if in location, limit_except 指定日志的格式。 语法: log_format name string ...; 默认值: log_format combined "..."; 上下文: http
  • 26. Proxy模块配置范例 proxy_temp_path /date/nginx/proxy_temp 1 2; proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=ng_cache:400m inactive=1d max_size=60g; location / { proxy_set_header Host $host; proxy_set_header Connection “”; proxy_http_version 1.1; proxy_cache_valid 302 5m; proxy_cache_valid 200 20d; proxy_cache_key "$scheme$host$request_uri"; proxy_cache ng_cache; proxy_pass http://localhost:8000; }
  • 27. 重新定义或者添加发往后端服务器的请求头。 语法: proxy_set_header field value; 默认值: proxy_set_header Host $proxy_host;proxy_set_header Connection close; 上下文: http, server, location 设置代理使用的HTTP协议版本。 语法: proxy_http_version 1.0 | 1.1; 默认值: proxy_http_version 1.0; 上下文: http, server, location 设置后端服务器的协议和地址。 语法: proxy_pass URL; 默认值: — 上下文: location, if in location, limit_exceptProxy模块
  • 28. 设置缓存的路径和其他参数。 语法: proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time]; 默认值: — 上下文: http 指定用于页面缓存的共享内存。 语法: proxy_cache zone | off; 默认值: proxy_cache off; 上下文: http, server, location Proxy模块
  • 29. 为不同的响应状态码设置不同的缓存时间。 语法: proxy_cache_valid [code ...] time; 默认值: — 上下文: http, server, location 定义如何生成缓存的键。 语法: proxy_cache_key string; 默认值: proxy_cache_key $scheme$proxy_host$request_uri; 上下文: http, server, location 设置响应被缓存的最小请求次数。 语法: proxy_cache_min_uses number; 默认值: proxy_cache_min_uses 1; 上下文: http, server, locationProxy模块
  • 30. Rewrite模块 配置范例 //多目录转成参数 if ($host ~* (.*)/.domain/.com) { set $sub_name $1; rewrite ^/sort//(/d+)//?$ /index.php?act=sort&cid=$sub_name&id=$1 last; } //目录对换 rewrite ^/(/d+)/(.+)/ /$2?id=$1 last; //在用户使用ie的使用重定向到/nginx-ie目录下。 if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /nginx-ie/$1 break; }
  • 31. Rewrite模块如果指定的正则表达式能匹配URI,此URI将被replacement参数定义的字符串改写。rewrite指令按其在配置文件中出现的顺序执行。 语法: rewrite regex replacement [flag]; 默认值: — 上下文: server, location, if 可选的flag参数可以是其中之一: last:停止执行当前这一轮的ngx_http_rewrite_module指令集,然后查找匹配改变后URI的新location; break:停止执行当前这一轮的ngx_http_rewrite_module指令集; redirect:在replacement字符串未以“http://”或“https://”开头时,使用返回状态码为302的临时重定向; permanent:返回状态码为301的永久重定向。
  • 32. Map模块 配置范例 map $uri $new { default http://www.domain.com/home/; /aa http://aa.domain.com/; /bb http://bb.domain.com/; ^/cc/(?P.*)$ http://cc.domain.com/$suffix; /john http://my.domain.com/users/john/; } map $uri $myvalue { /aa /mapped_aa; ~^/aa/(?.*)$ /mapped_bb/$suffix; }
  • 33. Map模块 变量设置的映射表。映射表由两列组成,匹配模式和对应的值。 语法: map string $variable { ... } 默认值: — 上下文: http 这个指令也支持三个特殊参数。 default value:如果源变量值没有匹配到任何变量,则设置一个默认值作为结果。 当没有设置 default,将会用一个空的字符串作为默认的结果。 hostnames:允许用前缀或者后缀掩码指定域名作为源变量值。 include file:包含一个或者多个存有映射值的文件。
  • 34. Upstream模块 配置范例 upstream backend { server backend1.example.com weight=5; server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; server backup1.example.com:8080 backup; keepalive 16; } 定义一组服务器 语法: upstream name { ... } 默认值: — 上下文: http
  • 35. Upstream模块 定义服务器的地址address和其他参数parameters。 语法: server address [parameters]; 默认值: — 上下文: upstream 可定义参数: weight=number。设定服务器的权重,默认是1。 max_fails=number。设定Nginx与服务器通信的尝试失败的次数。 fail_timeout=time。设定统计失败尝试次数的时间段,默认是10秒。 backup。标记为备用服务器。 down。标记服务器永久不可用,可以跟ip_hash指令一起使用。 激活对上游服务器的连接进行缓存。 语法: keepalive connections; 默认值: — 上下文: upstream
  • 36. Access模块 配置范例 location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2001:0db8::/32; deny all; }
  • 37. Access模块 允许指定的网络地址访问 语法: allow address | CIDR | all; 默认值: — 上下文: http, server, location, limit_except 拒绝指定的网络地址访问 语法: deny address | CIDR | all; 默认值: — 上下文: http, server, location, limit_except
  • 38. FastCGI模块 配置范例 upstream _fcgi { server 127.0.0.1:9000 weight=8; server 127.0.0.1:9001 weight=8; } location ~ .*.php?$ { #fastcgi_pass unix:/dev/shm/fcgi.sock; #fastcgi_pass 127.0.0.1:9000; fastcgi_pass _fcgi; include fastcgi.conf; fastcgi_buffer_size 128k; fastcgi_buffers 4 128k; fastcgi_connect_timeout 1800; }
  • 39. FastCGI模块 指定FastCGI服务器监听端口与地址。 语法: fastcgi_pass fastcgi-server 默认值: none 上下文: http, server, location 指定一些传递到FastCGI服务器的参数。 语法: fastcgi_param parameter value 默认值: — 上下文: http, server, location fastcgi.conf 指定同FastCGI服务器的连接超时时间,这个值不能超过75秒。 语法: fastcgi_connect_timeout time 默认值: fastcgi_connect_timeout 60 上下文: http, server, location
  • 40. 目 录介绍模块运维
  • 41. Php-fpm配置 配置范例。 [www] ;listen = /dev/shm/fcgi.sock listen = 9000 user = nobody group = nobody pm = dynamic pm.max_children = 512 pm.start_servers = 32 pm.min_spare_servers = 8 pm.max_spare_servers = 64 pm.max_requests = 4096 php-fpm.conf.in
  • 42. 系统优化-nginxworker数目设置 worker_processes 可用cpu核数; 使用epoll use epoll; 关闭访问日志 access_log off; 其它配置优化 worker_connections 65535; //每个进程允许的最多连接数 worker_rlimit_nofile 65535; //打开最多的文件描述符 keepalive_timeout 75s; //keepalive 超时时间 client_header_buffer_size 4k; //客户端请求头部的缓冲区大小
  • 43. 系统优化-内核参数 优化资源限制 #ulimit -n 1024 #ulimit –u 1024 修改open files 和 max user processes: 1,在/etc/rc.local 中增加一行 ulimit -SHn 65535 2,在/etc/profile 中增加一行 ulimit -SHn 65535 3,在/etc/security/limits.conf 最后增加: * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535
  • 44. 系统优化-内核参数优化内核参数 net.ipv4.tcp_max_tw_buckets = 6000 //timewait数量,默认180000。 net.ipv4.ip_local_port_range = 1024 65000 //允许系统打开的端口范围。 net.ipv4.tcp_tw_recycle = 1 //启用timewait 快速回收。 net.ipv4.tcp_tw_reuse = 1 //允许TIME-WAIT sockets重用于新TCP 连接。 net.ipv4.tcp_syncookies = 1 //出现SYN 等待队列溢出时启用cookies处理。 net.core.somaxconn = 262144 //web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。 net.core.netdev_max_backlog = 262144 //每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。 net.ipv4.tcp_max_orphans = 262144 //系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
  • 45. 系统优化-内核参数net.ipv4.tcp_max_syn_backlog = 262144 //记录的那些尚未收到客户端确认信息的连接请求的最大值。 net.ipv4.tcp_timestamps = 0 //时间戳可以避免序列号的卷绕。 net.ipv4.tcp_synack_retries = 1 //为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。 net.ipv4.tcp_syn_retries = 1 //在内核放弃建立连接之前发送SYN 包的数量。 net.ipv4.tcp_fin_timeout = 1 //如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。 net.ipv4.tcp_keepalive_time = 30 //当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。