Nginx学习总结:proxy与rewrite模块(三)
斜体下划线,表示建议采用默认配置,无需显式的配置
一、ngx_http_upstream_module
此模块中可配置的指令并不是很多。nginx的负载均衡算法包括:
1)round-robin:轮询,request将会依次有序的分发给web server。one by one!默认使用此算法。
2)least-connected:最小连接数,请求将会被分发给当前链接数最小的server。配置名“least_conn”。
3)ip-hash:根据请求的客户端IP作为hashing key,来判定选择哪个server。配置名“ip_hash”。
请求只会在“有效”的server间转发。
- upstream backend {
- least_conn;
- server 192.168.1.110:8080 weight=5;
- server 192.168.1.120:8080 max_fails=3 fail_timeout=12s;
- server 192.168.1.130 backup;
- }
- server {
- location / {
- proxy_pass http://backend;
- health_check;
- }
- }
1、upstream 【name】 {...}
上下文:http
默认情况下,nginx使用“round-robin”算法来选取为请求服务的web server,我们可选的算法有“ip_hash”、“least_conn”。如果web server失效,请求将会被分发给其他server。
2、server 【address】 【参数列表】
上下文:upstream
配置upstream中web server列表,可以使用“域名”,也可以使用“ip:port”方式,如果port没有指定,则默认位“80”;可选参数列表:
1)weight=【number】:设置server的权重,权重越高,其获取request量越大,默认为1。
2)max_fails=【number】:当server访问出错时,nginx重试的最大的失败次数,默认为1。如果仍然没有访问成功,则将此server标记为“failed”,此后的请求将不会在分发给它,直到nginx通过“heath_check”检测到它再次有效为止。
3)fail_timeout=【time】:重试的最长时间,默认位10s;nginx重试时,如果在“fail_timeout”时间内server仍没有链接成功,或者max_fails次数达到上限,那么此server将会标记为“failed”。
4)backup:将server标记为“backup”,即备份。当upstream中所有的主servers都失效时,“backup”才会接收请求。
5)down:将此server永久性的标记为“下线”,通常在运维时操作。如果希望某个机器下线(比如机器确实物理失效,或者在平滑上线过程中,需要将upstream server不再提供服务),我们需要将这些机器标注为“down”,此时那些server上正在执行的请求将会转发给其他server,请求不会中断。有时候,很多人将upstream中的server使用“#”注释,也能起到“server下线”的能力,但是这种方式往往会有一些隐患,比如那些正在执行的请求,将不会中断,而是继续执行,如果此时upstream server重启(上线时)可能会导致这些请求被挂起,简而言之,就是用户感觉访问“变慢了”。
3、health_check 【parameters】
上下文:location
这是一个很重要的选项,nginx周期性检测upstream中server列表的健康状况。
1)interval=【time】:默认值为5s,检测周期。
2)fails=【number】:连续失败多少次以后,此server被标记为“不可用”,默认为1。
3)passes=【number】:如果一个server被认为是“健康”之后,需要检测和确认的次数,默认为1。
4)uri=【uri】:检测server健康时所请求的URL,默认为“/”,通常我们会在web应用中单独做一个空页面或者说是健康探测页面。
5)match=【name】:需要声明一个match区块,根据match区块中的配置匹配“uri”响应的结果,匹配时认为server正常。默认响应的status为“2xx”、“3xx”。
- server {
- location / {
- proxy_pass http://backend;
- health_check match=welcome;
- }
- }
- match welcome {
- status 200;
- header Content-Type = text/html;
- body ~ "Welcome to nginx!";
- }
4、match 【name】 {...}
上下文:http
用于校验health_check请求的响应结果是否符合。match的规则比较简单,如下是允许的匹配方式:
1)status 200:响应代码为200。
2)status ! 500:响应代码不为500。
3)status 200 204:响应代码为“200”或者“204”。
4)status ! 301 302:响应代码不是301或者“302”。
5)status 200-399:响应代码为200~399区间。
以及上述各种表达的组合,比如“status ! 400-599”、“status 301-303 307”。
6)header Content-Type = text/html;:检测响应header。
7)header Content-Type != text/html;
8)header Connection ~ close:响应header中“Connection”字符正则匹配“close”。
9)header Connection !~ close:
10)header Host;:header中包含Host。
11)body ~ "welcome to nginx":body中的字符串正则匹配。
5、keepalive 【connections】
对当前upstream保持长连接的链接数,每个worker进程对当前upstream下所有的servers保持的长连接总数,注意此参数并不是用来设定http协议中的keep-alive选项的;如果超过此值,那么将根据LRU算法关闭其他多余的链接。此值并不会限制nginx与upstream之间链接的总数,通常情况下nginx与upstream之间总是创建新的短连接,即每次请求总是创建新的链接,请求结束后链接关闭(保留keepliave个链接)。此值应该相对较小,以便upstream server能够接受新的请求链接。简而言之,相对于upstream server,nginx就是http客户端,我们不应该保持大量链接。对于http 1.1而言,如果希望在连接上重置keep-alive选项,我们还需要清除Connection header部分:
- upstream backend {
- server 127.0.0.1:8080;
- keepalive 16;
- }
- server {
- ....
- location /http/ {
- proxy_pass http://backend;
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- }
- }
通常情况下,我们应该开启keepalive来提升nginx与tomcat之间的通信效率,毕竟短连接总会导致大量的创建和销毁(nginx端或者upstream后端出现大量的链接TIME_WAIT),当然后端的server(比如tomcat)也会干扰keepalive链接的数量,比如tomcat配置中最多保持150个长链接,那么即使nginx中设定此值为200也不会达到此值,因为tomcat已经将多余的链接关闭了。
6、queue 【number】【timeout=${time}】
如果一个upstream server在处理请求时不能立即被选中,这个请求将会被加入queue中,通过此指令,可以限制queue中最大的request个数,当queue满时、或者请求在queue中等待的时间超过timeout,则会向client返回502错误(Bad Gateway)。
二、ngx_http_proxy_module
用于将客户端请求转发给后端的server,通常与upstream模块一起使用。
1、proxy_buffers 【number】 【size】
上下文:http,server,location
“number”默认为8;“size”在32为平台下位4K,在64位平台为8K,即和一个内存页大小相等;此参数用来设定从后端server读取响应时使用的buffer空间,注意buffer的设定全部是针对一个链接而言(或者说是请求)。
2、proxy_buffer_size 【size】
上下文:http,server,location
默认值与“proxy_buffers”中“size”参数一致;设定用于保存后端server响应的第一部分内容的buffer大小,这部分包含一个小的响应的header。通常此值可以设置的更小。
3、proxy_buffering 【on | off】
上下文:http,server,location
默认值为“on”;设定是否buffer来自后端server的响应。
当“buffering”开启时,nginx将会缓存从后端server收到的响应,保存在“proxy_buffer_size”和“proxy_buffers”设定的buffer中;如果整个响应无法全部保存在buffer内存中,则剩余部分将会写入临时文件,临时文件由“proxy_max_temp_file_size”、“proxy_temp_file_write_size”设定。
当“buffering”关闭时,nginx收到响应后立即将会以同步的方式发送给客户端,nginx不会尝试读取整个响应(读取整个响应后才发送给客户端),nginx能够读取(等待客户端读取)的最大数据量为“proxy_buffer_size”。
buffering可以通过响应的header中“X-Accel-Buffering”来指定,可选值为“yes”或者“no”;当然nginx也可以通过“proxy_ignore_headers”来忽略这个header。
4、proxy_busy_buffers_size 【size】
上下文:http,server,location
默认值为“proxy_buffer_size”或者“proxy_buffers”的2倍。如果nginx边读取响应,同时还将buffer中的数据发送给客户端,那么这个buffer即为“busy”;当“buffering”开启时,此指令用于设定当响应尚未完全读取之前,nginx能够发送给客户端的最大buffer数据量;剩余的buffer,将会用于读取响应,如果buffer不足,将写入临时文件。处于“busy”状态的buffer,尽管已经发送,当仍然不能被当前请求回收重用。
5、proxy_max_temp_file_size 【size】
上下文:http,server,location
默认值为“1024m”;当“buffering”开启时,如果“proxy_buffer_size”无法全部保存响应内容,那么剩余的将会被写入临时文件,这个指令就是控制临时文件的最大尺寸。
“proxy_temp_file_write_size”指定每次写入临时文件的数据大小,默认值为“proxy_buffer_size”或者“proxy_buffers”的2倍。
6、proxy_temp_path 【path】【level】
上下文:http,server,location
设定一个Path用来保存临时文件,“path”用来设定临时文件的路径,其中level表示目录的层级,最大为3级,1级的目录名有一个字符表示,2级为2个,三级为三个(?),例如:
表示path下开启“1级”、“2级”目录。最终临时文件的路径看起来类似于:
7、proxy_cache 【zone | off】
上下文:http,server,location
默认值为“off”;声明当前location使用的cache名称,与其配合指令有“proxy_cache_key”、“proxy_cache_path”。zone名称由“proxy_cache_path”指令定义。
8、proxy_cache_path
上下文:http
这个指令很重要,用来指定proxy_cache有关的参数,是实现nginx静态资源缓存的重要配置之一。此指令指定cache在内存的占用空间、本地磁盘存储等等,本地文件名默认为“proxy_cache_key”的MD5值。指令格式:
- proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
1)levels:指定本地文件cache的目录层级,“1:2”表示开启1级、二级目录。
2)use_temp_path:如果此参数值缺省或者为“on”,则表示使用“proxy_temp_path”老保存cache的临时文件。
3)keys_zone:指定一个共享内存空间zone,用来缓存数据(key)。“proxy_cache”中可以共用此zone空间。
4)inactive:如果cache中的数据在此时间内没有被访问,那么数据将会从cache(本地文件中)移除,默认此值为“10m”。
5)max_size:cache存储的最大尺寸,当尺寸超过,将会基于LRU算法移除数据。nginx启动时,会创建一个“Cache manager”进程,通过“purge”方式移除数据。
6)loader_files:“cache loader”进程遍历文件时,每次加载的文件个数。默认为100.
7)loader_threshold:每次遍历消耗时间上限。默认为200毫秒。
8)loader_sleep:一次遍历之后,停顿的时间间隔,默认为50毫秒。
- #设置Web缓存区名称为cache_one,内存缓存空间大小为64MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
- proxy_temp_path /home/proxy_temp_dir;
- proxy_cache_path /home/proxy_cache_path levels=1:2 use_temp_path=off keys_zone=cache_one:64m inactive=1d max_size=30g;
- location / {
- proxy_next_upstream http_502 http_504 error timeout invalid_header;
- proxy_cache cache_one;
- proxy_cache_valid 200 304 30d;
- proxy_cache_valid 301 302 404 1m;
- proxy_cache_valid any 1m;
- proxy_cache_key $host$request_uri;
- add_header X-Proxy-Cache $upstream_cache_status;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header If-Modified-Since $http_if_modified_since;
- expires 30d;
- proxy_pass http://image;
- if_modified_since before;
- }
9、proxy_cache_valid 【code...】 【time】
上下文:http,server,location
针对不同的响应code设置不同的缓存时间。
如果响应代码为200,302,则缓存10分钟;如果为404,则缓存1分钟。其中“any”表示任意类型的code。
10、proxy_connect_timeout 【time】
上下文:http,server,location
默认值为“60s”;定义nginx与后端server建立链接的超时时间,此时间不能超过75秒。
11、proxy_hide_header 【field】
上下文:http,server,location
默认nginx不会将响应中的“Date”、“Server”、“X-Pad”、“X-Accel-...”等headers发送给客户端。“proxy_hide_header”指令设置不需要发送的额外的field;反之,对于可以传递给客户端的filed,通过“proxy_pass_header”指令指定。
12、proxy_http_version 【1.0 | 1.1】
上下文:http,server,location
默认值为“1.0”;指定与后端server通信时使用的http协议的版本,在与“keepalive”链接配合使用时,建议此值为“1.1”。
13、proxy_ignore_headers 【field...】
上下文:http,server,location
指定来自后端server的响应中的某些header不会被处理,如下几个fields可以被ignore:“X-Accel-Redirect”、“X-Accel-Expires”、“X-Accel-Limit-Rate”、“X-Accel-Buffering”、“X-Accel-Charset”、“Expires”、“Cache-Control”、“Set-Cookie”、“Vary”。“不被处理”就是nginx不会尝试解析这些header并应用它们,比如nginx处理来自后端server的“Expires”,将会影响它本地的文件cache的机制。
14、proxy_intercept_errors 【on | off】
上下文:http,server,location
默认值为“off”;当后端server的响应code >= 300时,是否跳转到“error_page”指令指定的错误页面上。如果为“off”,将nginx不做拦截,直接戒后端server的响应返回给客户端。
15、proxy_next_upstream
上下文:http,server,location
此指令很重要,用来设定当何种情况下,请求将会被转发给下一个后端server。此指令允许的参数列表为:
1)error:当nginx与后端server建立连接、发送请求、读取响应header时,发生错误。
2)timeout:当nginx与后端server在建立链接、发送请求(write)、读取响应header(read)时,操作超时。
3)invalid_header:如果后端server返回空的或者无效的header时。
4)http_500、http_502、http_503、http_504、http_403、http_404:后端server返回指定的错误code时。
5)off:不将请求转发给下一个server,直接响应错误code。(在生产环境中,建议不要关闭,这会对部署期间的用户访问带来不良影响,此时nginx会以错误的方式返回给Client,无论你的nginx是否down了此upstream server)
6)non_idempotent:默认情况下nginx不会对“non_idempotent”类型的请求转发给next upstream(比如post请求如果在一个upstream server上超时,将不会转发给下一个upstream,此前的版本,没有这个限制,所以会导致表单重复提交等问题,nginx终于解决了这个问题),1.9.13版本新增参数;如果指定了此参数,则明确表示对于“POST、LOCK、PATCH”等类型的请求可以转发给next upstream。
需要注意的时,只有nginx尚未将任何响应内容发送给客户端之前出现上述错误,才会将请求转发给下一个server。
16、proxy_pass 【URL】
上下文:location
设置转发给后端server时请求所使用的HTTP协议和URI,协议可以为“http”、“https”;地址可以为“域名”、“ip”,其中port是可选的,默认为80。
如果proxy_pass指令指定了URI,那么请求中匹配location部分的URI将会被替换:
- location /name {
- proxy_pass http://127.0.0.1:8080/other;
- }
- #http://exampe.org/name/a.jhtml将会被转发给:
- #http://127.0.0.1:8080/other/a.jhtml
如果location中使用了uri,但是proxy_pass中没有使用,那么请求的uri将会全部添加到proxy_pass指定的路径之后。
- location /name {
- proxy_pass http://127.0.0.1:8080;
- }
- #请求url为http://example.org/name/a.jhtml将会被转发到
- #http://127.0.0.1:8080/name/a.jhtml
如果location中使用了正则表达式,那么在proxy_pass指令中不应该指定uri,否则uri的替换是无法断定的。
如果在location中使用了“rewrite”指令(break)对请求的uri进行了修改,那么proxy_pass指令中的uri将会被忽略,被rewrite之后的全量uri将会传递给server。
- location /name {
- rewrite /name/([^/]+) /users?name=$1 break;
- proxy_pass http://127.0.0.1;
- }
- #http://exmaple.org/name/zhangsan,将会转发到
- #http://127.0.0.1/users?name=zhangsan
其中server名称、端口、uri等均可以使用变量:
17、proxy_pass_header 【field】
上下文:http,server,location
上述我们已经知道,“proxy_hide_header”指令默认不会把几个header传递给client,那么“proxy_pass_header”则允许其中某个header传递给客户端。
18、proxy_pass_request_body 【on | off】
上下文:http,server,location
默认值为“on”,不建议修改此值;是否将原始的请求body转发给后端server。如果你需要nginx对body进行裁剪,然后再转发给后端server,那么此处可以设定为“off”。
19、proxy_pass_request_header 【on | off】
上下文:http,server,location
默认值为“on”,不建议修改此值;指定是否将请求的原始header转发给后端的server。如果在某些场景下,nginx需要忽略所有的请求header,或者对header进行改造时,可以关闭此值。
20、proxy_read_timeout 【time】
上下文:http,server,location
默认值为“60s”;设定nginx从后端server读取响应时的超时时间,此时间为两次read操作之间阻塞的最大时间,而非整个响应的读取耗时。
21、proxy_send_timeout 【time】
上下文:http,server,location
默认为“60s”;nginx将响应发送给客户端时最长的阻塞时间。同上。
22、proxy_set_header 【field】【value】
上下文:http,server,location
默认值为:
此指令的作用是,将请求发送给后端server之前,重新设置或者append指定的header的值。当然我们也可以重新设置上述两个header。
二、proxy模块中内置的变量
1、$proxy_host:在“proxy_pass”指令中指定的后端server的名称和端口。通常指nginx选择的后端server。($http_host指原始请求中“Host” header的值,此值可能为空;$host指nginx根据请求中Host域匹配的“server_name”值,此值通常与“$http_host”一样,如果http_host为空,此值将为首个匹配的“server_name”)
2、$proxy_port:在“proxy_pass”指令中指定的后端server的端口,或者是协议的默认端口。
3、$proxy_add_x_forwarded_for:其值为请求头“X-Forwarded-For”值,追加“$remote_addr”,中间通过“,”分割。如果“X-Forwarded-For”值为空,那么最终“$proxy_add_x_forwarded_for”的值和“$remote_addr”相等;如果此请求经过了多个nginx转发链路,那么此值应该能够表达nginx的转发过程,那么此值的第一个“,”之前的部分才是原始的客户端地址。
三、ngx_http_rewrite_module
此模块根据正则表达式改变请求的URI、重定向请求等。
1、break;
上下文:server,location
这个指令不需要任何参数;它的本身语义同“break”(中断),停止处理当前rewrite模块中的其他指令。如果此指令在“location”区块中,后续的请求处理,将会继续。
2、return
上下文:server,location
此指令的语法为:
1)return 【code】【text】:停止处理,并向客户端返回指定code,其中text是响应的文本内容。
2)return 【code】【url】:code值通常为301、302、303、307,url为客户端需要重定向的地址。
3)return 【url】:向客户端返回302代码,并重定向到指定url。
3、rewrite 【regex】【replacement】【flag】
上下文:server,location
使用正在表达式对原始uri进行改变。rewrite指令按照其在配置中声明的顺序执行,可能flag会提前终止执行后续的指令。如果“replacement”以“http://”、“https://”开头,替换uri后,终止处理后续指令,直接将重定向返回给客户端(302)。“flag”的可选值为:
1)last:停止处理当前rewrite模块中的指令,根据改变后的uri,重新开始查找新的location配置。(server,location区块中)
2)break:停止处理当前rewrite模块中的指令,继续执行此location区块中非rewrite指令。(location区块中)
3)redirect:工作原理同“return url”;不过“replacement”不以“http”、“https”开头,将rewrite之后的url重定向给客户端,响应code为302。
4)permanent:同3),永久重定向,返回code为301。
- server {
- listen 80;
- server_name exmaple.org www.example.org .example.org
- rewrite ^/(.*)$ https://$host/$1 last;
- }
- server {
- listen 443;
- server_name www.xuehaodai.com xuehaodai.com;
- ssl on;
- ssl_certificate /usr/local/nginx/conf/ssl/example_org.crt;
- ssl_certificate_key /usr/local/nginx/conf/ssl/example_org.key;
- ssl_session_timeout 5m;
- ssl_protocols SSLv3 TLSv1 TLSv1.2 TLSv1.1;
- ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;
- ssl_prefer_server_ciphers on;
- location / {
- ...
- }
- }
该文转自https://www.iteye.com/blog/shift-alt-ctrl-2229578
白驹过隙,当看到比你优秀的人比你还努力的时候,你也会越来越优秀,相信越努力越幸运!