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间转发。

Java代码   收藏代码
  1. upstream backend {  
  2.     least_conn;  
  3.     server 192.168.1.110:8080 weight=5;  
  4.     server 192.168.1.120:8080 max_fails=3 fail_timeout=12s;  
  5.     server 192.168.1.130 backup;  
  6. }  
  7.    
  8. server {  
  9.     location / {  
  10.         proxy_pass http://backend;  
  11.         health_check;  
  12.     }  
  13. }  

 

    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”。

Java代码   收藏代码
  1. server {  
  2.     location / {  
  3.         proxy_pass http://backend;  
  4.         health_check match=welcome;  
  5.     }  
  6. }  
  7. match welcome {  
  8.     status 200;  
  9.     header Content-Type = text/html;  
  10.     body ~ "Welcome to nginx!";  
  11. }  

 

    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部分:

Java代码   收藏代码
  1. upstream backend {  
  2.     server 127.0.0.1:8080;  
  3.     keepalive 16;  
  4. }  
  5. server {  
  6.     ....  
  7.     location /http/ {  
  8.         proxy_pass http://backend;  
  9.         proxy_http_version 1.1;  
  10.         proxy_set_header Connection "";  
  11.     }  
  12. }  

 

    通常情况下,我们应该开启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个,三级为三个(?),例如:

Java代码   收藏代码
  1. proxy_temp_path /home/data/nginx/tmp 2;  

    表示path下开启“1级”、“2级”目录。最终临时文件的路径看起来类似于:

Java代码   收藏代码
  1. /home/data/nginx/tmp/7/45/00000123457  

    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值。指令格式:

Java代码   收藏代码
  1. 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毫秒。

Java代码   收藏代码
  1. #设置Web缓存区名称为cache_one,内存缓存空间大小为64MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。  
  2. proxy_temp_path   /home/proxy_temp_dir;  
  3. proxy_cache_path  /home/proxy_cache_path levels=1:2 use_temp_path=off keys_zone=cache_one:64m inactive=1d max_size=30g;  
  4. location / {  
  5.     proxy_next_upstream http_502 http_504 error timeout invalid_header;  
  6.         proxy_cache cache_one;  
  7.         proxy_cache_valid 200 304 30d;  
  8.         proxy_cache_valid 301 302 404 1m;  
  9.         proxy_cache_valid any 1m;  
  10.         proxy_cache_key $host$request_uri;  
  11.   
  12.     add_header X-Proxy-Cache $upstream_cache_status;  
  13.         proxy_set_header  Host $host;  
  14.         proxy_set_header  X-Real-IP  $remote_addr;  
  15.         proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;  
  16.         proxy_set_header X-Forwarded-For $remote_addr;  
  17.         proxy_set_header If-Modified-Since $http_if_modified_since;  
  18.     expires 30d;  
  19.     proxy_pass http://image;  
  20.         if_modified_since before;  
  21. }  

    9、proxy_cache_valid 【code...】 【time】

        上下文:http,server,location

    针对不同的响应code设置不同的缓存时间。

Java代码   收藏代码
  1. proxy_cache_valid 200 302 10m;  
  2. proxy_cache_valid 404 1m;  
  3. proxy_cache_valid any 1m;  

    如果响应代码为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的响应返回给客户端。

Java代码   收藏代码
  1. proxy_intercept_errors on;  
  2. error_page 404 /404.html;  
  3. error_page 500 502 503 504 /50x.html  

    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将会被替换:

Java代码   收藏代码
  1. location /name {  
  2.     proxy_pass http://127.0.0.1:8080/other;  
  3. }  
  4. #http://exampe.org/name/a.jhtml将会被转发给:  
  5. #http://127.0.0.1:8080/other/a.jhtml  

   如果location中使用了uri,但是proxy_pass中没有使用,那么请求的uri将会全部添加到proxy_pass指定的路径之后。

Java代码   收藏代码
  1. location /name {  
  2.     proxy_pass http://127.0.0.1:8080;  
  3. }  
  4. #请求url为http://example.org/name/a.jhtml将会被转发到  
  5. #http://127.0.0.1:8080/name/a.jhtml  

 

    如果location中使用了正则表达式,那么在proxy_pass指令中不应该指定uri,否则uri的替换是无法断定的。

    如果在location中使用了“rewrite”指令(break)对请求的uri进行了修改,那么proxy_pass指令中的uri将会被忽略,被rewrite之后的全量uri将会传递给server。

Java代码   收藏代码
  1. location /name {  
  2.     rewrite /name/([^/]+) /users?name=$break;  
  3.     proxy_pass http://127.0.0.1;  
  4. }  
  5. #http://exmaple.org/name/zhangsan,将会转发到  
  6. #http://127.0.0.1/users?name=zhangsan  

    其中server名称、端口、uri等均可以使用变量:

Java代码   收藏代码
  1. proxy_pass http://$host$uri;  
  2. ##等价于  
  3. proxy_pass $request;  

    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

    默认值为:

Java代码   收藏代码
  1. proxy_set_header Host $proxy_host;  
  2. proxy_set_header Connection close;  

    此指令的作用是,将请求发送给后端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”区块中,后续的请求处理,将会继续。

Java代码   收藏代码
  1. if ($slow) {  
  2.     limit_rate 10k;  
  3.     break;  
  4. }  

    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。

Java代码   收藏代码
  1. server {  
  2.     listen 80;  
  3.     server_name exmaple.org www.example.org .example.org  
  4.     rewrite ^/(.*)$  https://$host/$1 last;  
  5.  }  
  6. server {  
  7.     listen 443;  
  8.     server_name www.xuehaodai.com xuehaodai.com;  
  9.   
  10.     ssl on;  
  11.     ssl_certificate      /usr/local/nginx/conf/ssl/example_org.crt;  
  12.     ssl_certificate_key  /usr/local/nginx/conf/ssl/example_org.key;  
  13.     ssl_session_timeout  5m;  
  14.     ssl_protocols  SSLv3 TLSv1 TLSv1.2 TLSv1.1;  
  15.     ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;  
  16.     ssl_prefer_server_ciphers   on;  
  17.   
  18.     location  / {  
  19.     ...  
  20.     }  
  21. }  

 

该文转自https://www.iteye.com/blog/shift-alt-ctrl-2229578

白驹过隙,当看到比你优秀的人比你还努力的时候,你也会越来越优秀,相信越努力越幸运!

你可能感兴趣的:(Nginx学习总结:proxy与rewrite模块(三))