一、nginx配置相关概念
Nginx的代码是由一个核心和一系列的模块组成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能;还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。不过,大多跟协议相关的功能和某应用特有的功能都是由nginx的模块实现的。这些功能模块大致可以分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了nginx的http功能。事件模块主要用于提供OS独立的(不同操作系统的事件机制有所不同)事件通知机制如kqueue或epoll等。协议模块则负责实现nginx通过http、tls/ssl、smtp、pop3以及imap与对应的客户端建立会话。
Nginx的核心模块为Main和Events,此外还包括标准HTTP模块、可选HTTP模块和邮件模块,其还可以支持诸多第三方模块。Main用于配置错误日志、进程及权限等相关的参数,Events用于配置IO模型,如epoll、kqueue、select或poll等,它们是必备模块。
Nginx的主配置文件由几个段组成,这个段通常也被称为nginx的上下文,每个段的定义格式如下所示。需要注意的是,其每一个指令都必须使用分号(;)结束,否则为语法错误。
<section> {
<directive> <parameters>;
}
配置文件结构:
user nobody nobody; worker_processes 4; worker_rlimit_nofile 51200; error_log logs/error.log notice; pid /var/run/nginx.pid; events { use epoll; worker_connections 51200; } http { http服务的相关配置
upstream tomcat { 实现负载均衡 } server { location / { } }
二、各服务模块配置(模块中均给出重要参数)
1、配置main、Events模块
2、HTTP相关配置
3、虚拟服务器相关配置
4、location相关的配置
5、反向代理
6、负载均衡
7、反向代理性能优化
8、压缩
9、nginx限速配置
1、配置main模块和event模块
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 1024;
}
1.1.1 error_log
用于配置错误日志,可用于main、http、server及location上下文中;语法格式为:
error_log file | stderr [ debug | info | notice | warn | error | crit | alert | emerg ]
如果在编译nginx时使用了--with-debug选项,还可以使用如下格式打开调试功能。
error_log LOGFILE [debug_core | debug_alloc | debug_mutex | debug_event | debug_http | debug_imap];
要禁用错误日志,不能使用“error_log off;”,而要使用类似如下选项:
error_log /dev/null crit;
1.1.2 timer_resolution
用于降低gettimeofday()系统调用的次数。默认情况下,每次从kevent()、epoll、/dev/poll、select()或poll()返回时都会执行此系统调用。语法格式为:
timer_resolution interval
例如:
timer_resolution 100ms;
1.1.3 worker_cpu_affinity
通过sched_setaffinity()将worker绑定至CPU上,只能用于main上下文。语法格式为:
worker_cpu_affinity cpumask ...
例如:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;1.1.4 worker_priority
为worker进程设定优先级(指定nice值),此参数只能用于main上下文中,默认为0;语法格式为:
worker_priority number
1.1.5 worker_processes
worker进程是单线程进程。如果Nginx用于CPU密集型的场景中,如SSL或gzip,且主机上的CPU个数至少有2个,那么应该将此参数值设定为与CPU核心数相同;如果Nginx用于大量静态文件访问的场景中,且所有文件的总大小大于可用内存时,应该将此参数的值设定得足够大以充分利用磁盘带宽。
此参数与Events上下文中的work_connections变量一起决定了maxclient的值:
maxclients = work_processes * work_connections1.1.6 worker_rlimit_nofile
设定worker进程所能够打开的文件描述符个数的最大值。语法格式:
worker_rlimit_nofile number
2.2 配置Events模块
2.2.1 worker_connections
设定每个worker所处理的最大连接数,它与来自main上下文的worker_processes一起决定了maxclients的值。
max clients = worker_processes * worker_connections
而在反向代理场景中,其计算方法与上述公式不同,因为默认情况下浏览器将打开2个连接,而nginx会为每一个连接打开2个文件描述符,因此,其maxclients的计算方法为:
max clients = worker_processes * worker_connections
示例:
user nginx; # the load is CPU-bound and we have 16 cores worker_processes 16; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { use epoll; worker_connections 2048; }
2、http服务的相关配置
http上下文专用于配置用于http的各模块,此类指令非常的多,每个模块都有其专用指定,具体请参数nginx官方wiki关于模块部分的说明。大体上来讲,这些模块所提供的配置指令还可以分为如下几个类别。 客户端类指令:如client_body_buffer_size、client_header_buffer_size、client_header_timeout和keepalive_timeout等; 文件IO类指令:如aio、directio、open_file_cache、open_file_cache_min_uses、open_file_cache_valid和sendfile等; hash类指令:用于定义Nginx为某特定的变量分配多大的内存空间,如types_hash_bucket_size、server_names_hash_bucket_size和variables_hash_bucket_size等; 套接字类指令:用于定义Nginx如何处理tcp套接字相关的功能,如tcp_nodelay(用于keepalive功能启用时)和tcp_nopush(用于sendfile启用时)等;
3、虚拟服务器相关配置
server { <directive> <parameters>; } 用于定义虚拟服务器相关的属性,常见的指令有backlog、rcvbuf、bind及sndbuf等。
4、location相关的配置
location [modifier] uri {...} 或 location @name {…} 通常用于server上下文中,用于设定某URI的访问属性。location可以嵌套。 The prefix "@" specifies a named location. Such locations are not used during normal processing of requests, they are intended only to process internally redirected requests (see error_page, try_files). 如下面关于memcached的相关配置。 server { location / { set $memcached_key $uri; memcached_pass name:11211; default_type text/html; error_page 404 @fallback; } location @fallback { proxy_pass http://backend; } }
5、反向代理
Nginx通过proxy模块实现反向代理功能。在作为web反向代理服务器时,nginx负责接收客户请求,并能够根据URI、客户端参数或其它的处理逻辑将用户请求调度至上游服务器上(upstream server)。nginx在实现反向代理功能时的最重要指令为proxy_pass,它能够将location定义的某URI代理至指定的上游服务器(组)上。如下面的示例中,location的/uri将被替换为上游服务器上的/newuri。 location /uri { proxy_pass http://www.magedu.com:8080/newuri;} 不过,这种处理机制中有两个例外。一个是如果location的URI是通过模式匹配定义的,其URI将直接被传递至上游服务器,而不能为其指定转换的另一个URI。例如下面示例中的/forum将被代理为http://www.magedu.com/forum。location ~ ^/bbs { proxy_pass http://www.magedu.com;} 第二个例外是,如果在loation中使用的URL重定向,那么nginx将使用重定向后的URI处理请求,而不再考虑上游服务器上定义的URI。如下面所示的例子中,传送给上游服务器的URI为/index.php?page=<match>,而不是/index。 location / { rewrite /(.*)$ /index.php?page=$1 break; proxy_pass http://localhost:8080/index;}
proxy模块的可用配置指令非常多,它们分别用于定义proxy模块工作时的诸多属性,如连接超时时长、代理时使用http协议版本等。下面对常用的指令做一个简单说明。
proxy_connect_timeout:nginx将一个请求发送至upstream server之前等待的最大时长;
proxy_cookie_domain:将upstream server通过Set-Cookie首部设定的domain属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量;
proxy_cookie_path: 将upstream server通过Set-Cookie首部设定的path属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量;
proxy_hide_header:设定发送给客户端的报文中需要隐藏的首部;
proxy_pass:指定将请求代理至upstream server的URL路径;
proxy_set_header:将发送至upsream server的报文的某首部进行重写;
proxy_redirect:重写location并刷新从upstream server收到的报文的首部;
proxy_send_timeout:在连接断开之前两次发送至upstream server的写操作的最大间隔时长;
proxy_read_timeout:在连接断开之前两次从接收upstream server接收读操作的最大间隔时长;
如下面的一个示例:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 30;
proxy_send_timeout 15;
proxy_read_timeout 15;
6、反向代理后,往往还需要做负载均衡,需要对后端服务器做负载均衡
负载均衡用到了 upstram模块
upstream模块常用的指令有: ip_hash:基于客户端IP地址完成请求的分发,它可以保证来自于同一个客户端的请求始终被转发至同一个upstream服务器; keepalive:每个worker进程为发送到upstream服务器的连接所缓存的个数; least_conn:最少连接调度算法; server:定义一个upstream服务器的地址,还可包括一系列可选参数,如: weight:权重; max_fails:最大失败连接次数,失败连接的超时时长由fail_timeout指定; fail_timeout:等待请求的目标服务器发送响应的时长; backup:用于fallback的目的,所有服务均故障时才启动此服务器; down:手动标记其不再处理任何请求; 例如: upstream backend { server www.magedu.com weight=5; server www2.magedu.com:8080 max_fails=3 fail_timeout=30s; } upstream模块的负载均衡算法主要有三种,轮调(round-robin)、ip哈希(ip_hash)和最少连接(least_conn)三种。 此外,upstream模块也能为非http类的应用实现负载均衡,如下面的示例定义了nginx为memcached服务实现负载均衡之目的。 upstream memcachesrvs { server 172.16.100.6:11211; server 172.16.100.7:11211; } server { location / { set $memcached_key "$uri?$args"; memcached_pass memcachesrvs; error_page 404 = @fallback; } location @fallback { proxy_pass http://127.0.0.1:8080;} }
7、反向代理性能优化
缓冲区设定
nginx在默认情况下在将其响应给客户端之前会尽可能地接收来upstream服务器的响应报文,它会将这些响应报文存暂存于本地并尽量一次性地响应给客户端。然而,在来自于客户端的请求或来自upsteam服务器的响应过多时,nginx会试图将之存储于本地磁盘中,这将大大降低nginx的性能。因此,在有着更多可用内存的场景中,应该将用于暂存这些报文的缓冲区调大至一个合理的值。 proxy_buffer_size size:设定用于暂存来自于upsteam服务器的第一个响应报文的缓冲区大小; proxy_buffering on|off:启用缓冲upstream服务器的响应报文,否则,如果proxy_max_temp_file_size指令的值为0,来自upstream服务器的响应报文在接收到的那一刻将同步发送至客户端;一般情况下,启用proxy_buffering并将proxy_max_temp_file_size设定为0能够启用缓存响应报文的功能,并能够避免将其缓存至磁盘中; proxy_buffers 8 4k|8k:用于缓冲来自upstream服务器的响应报文的缓冲区大小;
缓存
nginx做为反向代理时,能够将来自upstream的响应缓存至本地,并在后续的客户端请求同样内容时直接从本地构造响应报文。 proxy_cache zone|off:定义一个用于缓存的共享内存区域,其可被多个地方调用;缓存将遵从upstream服务器的响应报文首部中关于缓存的设定,如 "Expires"、"Cache-Control: no-cache"、 "Cache-Control: max-age=XXX"、"private"和"no-store" 等,但nginx在缓存时不会考虑响应报文的"Vary"首部。为了确保私有信息不被缓存,所有关于用户的私有信息可以upstream上通过"no-cache" or "max-age=0"来实现,也可在nginx设定proxy_cache_key必须包含用户特有数据如$cookie_xxx的方式实现,但最后这种方式在公共缓存上使用可能会有风险。因此,在响应报文中含有以下首部或指定标志的报文将不会被缓存。 Set-Cookie Cache-Control containing "no-cache", "no-store", "private", or a "max-age" with a non-numeric or 0 valueExpires with a time in the past X-Accel-Expires: 0 proxy_cache_key:设定在存储及检索缓存时用于“键”的字符串,可以使用变量为其值,但使用不当时有可能会为同一个内容缓存多次;另外,将用户私有信息用于键可以避免将用户的私有信息返回给其它用户; proxy_cache_lock:启用此项,可在缓存未命令中阻止多个相同的请求同时发往upstream,其生效范围为worker级别; proxy_cache_lock_timeout:proxy_cache_lock功能的锁定时长; proxy_cache_min_uses:某响应报文被缓存之前至少应该被请求的次数; proxy_cache_path:定义一个用记保存缓存响应报文的目录,及一个保存缓存对象的键及响应元数据的共享内存区域(keys_zone=name:size),其可选参数有: levels:每级子目录名称的长度,有效值为1或2,每级之间使用冒号分隔,最多为3级; inactive:非活动缓存项从缓存中剔除之前的最大缓存时长; max_size:缓存空间大小的上限,当需要缓存的对象超出此空间限定时,缓存管理器将基于LRU算法对其进行清理; loader_files:缓存加载器(cache_loader)的每次工作过程最多为多少个文件加载元数据; loader_sleep:缓存加载器的每次迭代工作之后的睡眠时长; loader_threashold:缓存加载器的最大睡眠时长; 例如: proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m; proxy_cache_path /data/nginx/cache/two levels=2:2 keys_zone=two:100m; proxy_cache_path /data/nginx/cache/three levels=1:1:2 keys_zone=three:1000m; proxy_cache_use_stale:在无法联系到upstream服务器时的哪种情形下(如error、timeout或http_500等)让nginx使用本地缓存的过期的缓存对象直接响应客户端请求;其格式为: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off proxy_cache_valid [ code ...] time:用于为不同的响应设定不同时长的有效缓存时长,例如:proxy_cache_valid 200 302 10m; proxy_cache_methods [GET HEAD POST]:为哪些请求方法启用缓存功能; proxy_cache_bypass string:设定在哪种情形下,nginx将不从缓存中取数据;例如: proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment; proxy_cache_bypass $http_pragma $http_authorization;
8、压缩
nginx将响应报文发送至客户端之前可以启用压缩功能,这能够有效地节约带宽,并提高响应至客户端的速度。通常编译nginx默认会附带gzip压缩的功能,因此,可以直接启用之。 http { gzip on; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json; gzip_disable msie6; } gzip_proxied指令可以定义对客户端请求哪类对象启用压缩功能,如“expired”表示对由于使用了expire首部定义而无法缓存的对象启用压缩功能,其它可接受的值还有“no-cache”、“no-store”、“private”、“no_last_modified”、“no_etag”和“auth”等,而“off”则表示关闭压缩功能。
9、nginx限速配置
nginx的限速功能通过limit_zone、limit_conn和limit_rate指令进行配置。首先需要在http上下文配置一个limit_zone,然后在需要的地方使用limit_conn和limit_rate 进行限速设置。下面是一个简单的例子。 http { limit_zone first $binary_remote_addr 10m; server { location /downloads/ { limit_conn first 1; limit_rate 50k; } } } 说明: limit_zone:语法格式“limit_req_zone $variable zone=name:size rate=rate;”,实现针对每个IP定义一个存储session状态的容器。这个示例中定义了一个名叫first的10m大小的容器,这个名字会在后面的limit_conn中使用。 limit_conn first 1; 限制在first中记录状态的每个IP只能发起一个并发连接。 limit_rate 50k; 对每个连接限速50k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许三个并发连接,那么这个IP就是限速为limit_rate×3,在设置的时候要根据自己的需要做设置调整,要不然会达不到自己希望的目的。 限制连接数的配置如下所示。 limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; server { ... limit_conn perip 10; limit_conn perserver 100; }
转载于:https://blog.51cto.com/xz159065974/1403412