6、nginx的反向代理及缓存功能

nginx模块的应用

ngx_http_proxy_module  nginx 反向代理模块: http://nginx.org/en/docs/http/ngx_http_proxy_module.html

http://www.dongshi.com 

server {

listen

server_name

location / {

proxy_pass http://192.168.184.141:80/;  //指明把用户所有对路径"/"的请求都转发到后端所指定的服务器:192.168.184.141:80

}

}

 

location / {
    proxy_pass       http://localhost:8000;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
}

proxy_set_header Host $host 这条的意义是:

假如一台web服务器有两个虚拟主机:http://www.dongshi.com和http://mysql.dongshi.com两个不同的站点,无论客户端访问哪个站点,代理服务器都统统代理到141这台主机上。如果141这台服务器对代理服务器来讲有虚拟主机并且基于名称来访问,一定只有默认主机来响应。所以代理服务器在向后端web服务器发送时,发送的是用户请求的名称即(http://www.dongshi.com或http://mysql.dongshi.com),所以代理服务器还要把用户原来请求的域名转发至后端,后端服务器才能评判到底客户端请求的是哪一个虚拟主机。这就是proxy_set_header Host $host的意义。set_header是设置请求报文的,这里是设置HOST的请求报文,值为$host即客户端请求时的变量。变量$host充当发往后端时HOST的值,HOST是实现基于主机名的虚拟主机的重要首部信息。

proxy_set_header X-Real-IP $remote_addr的作用:

http模块有很多变量,$remote_addr是http模块自带的变量,这个变量记录的是客户端的IP地址,把$remote_addr这个变量的值当作X-Real-IP(=新首部的值),发往后端时首部的值。

当用户请求到达nginx时,nginx是作为web服务器的,只不过自己不提供内容,而是重新封装请求,到后端服务器去获取相关内容。这个过程分为两个阶段:第一个阶段是请求报文从客户端到代理服务器的过程,叫web proxy或reverse proxy。此阶段请求报文从客户端发送到代理服务器端时,这个报文应该有http的请求首部,这个首部到达nginx(即代理服务器)后,nginx会把首部拆除,以了解客户端请求的内容是什么,并匹配本地location,一旦匹配到却发现要代理到后端服务器去请求的,那么nginx(即代理服务器)就会重新构建请求报文,并送到后端服务器上去,此时这个请求报文在传输过程中也应该有请求首部的。

报文B的源地址是CIP,目标地址是PIP(proxy ip),源端口在客户端是随机端口,目标端口是80端口,此时在location中查找之后,通过proxy_pass需要将请求报文代理至后端服务器的情况下就需要把报文在代理服务器上重新构建。当报文位于报文D的位置时,源IP是LIP(location ip),目标IP是UIP(upstream ip),此时源端口是随机的,目标端口是web服务器E的监听web服务端口。此时后端的web服务器E记录日志时,源IP是代理服务器的LIP,这对日志并没有多大的作用,因为记录日志是为了了解哪些客户端访问了web服务器E,所以可以在报文D上进行设置,即在目标UIP后面加一个自定义的首部,UIP:CIP,这样并不妨碍代理服务器把报文送往web服务器E,同时web服务器E在记录日志时,也可以只记录CIP,不记录LIP。所以这就是:proxy_set_header X-Real-IP $remote_addr的作用。

 

生产模式下,代理服务器是公网地址,LIP是内网地址,UIP也是私网地址,可以有效隐藏后端web服务器。

示例

反向代理报文格式:

location  /uri {

rewrite

proxy_pass http://back_server:port/newuri;

}

/uri --> /newuri    其中"/uri"是指用户请求的,而"/newurl"是提供web服务器的后端的uri,两者可能不一样的

这种处理机制有两个例外:

1、如果location后面的 /uri 是通过模式匹配的(比如:~ /uri或者~* /uri),即是这种模式:location ~ 或 ~* /uri ,其/uri将被补在后面,

   即proxy_pass http://back_server:port/uri;而不是把/uri映射为proxy_pass http://back_server:port/newuri;

2、如果location中使用了url重定向,那么nginx将使用重定向后的uri进行处理

如:

location  /uri {

rewrite

proxy_pass http://back_server:port/newuri;  //此时这里的newuri不再有效了,而是把rewirte重读后的路径直接把newuri替换了。

}

 

下面先演示没有模式匹配的,直接向后端web sever映射的

1、首先安装nginx(192.168.184.141),然后配置好后端服务器的页面文件

# vim /etc/nginx/conf.d/default.conf

把默认页面/usr/share/nginx/html改为/var/www/html

# mkdir /var/www/html -pv

#vim /var/www/html/index.html

<h1>Web Server on 192.168.184.141</h1>

下面是在代理服务器192.168.184.142上的配置

2、# vim /etc/nginx/nginx.conf    //打开文件可以看到最后一行

include /etc/nginx/conf.d/*.conf;    //其中 *.conf 中定义的是虚拟主机

3、# cd /etc/nginx/conf.d/    //进入这个目录,可以看到有一个default.conf,打开文件可以看到里面定义的默认server

server {                      //这个是默认server
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {   //默认的页面文件
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #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 {
        root   /usr/share/nginx/html;
    }   

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #   
    #location ~ .php$ {
    #    proxy_pass   http://127.0.0.1;
    #}  

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #   
    #location ~ .php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /.ht {
    #    deny  all;
    #}
}

4、# cp default.conf default.conf.bak   //在对默认server文件进行修改之前应该先进行备份

5、# vim default.conf   

location / {

#root /usr/share/nginx/html;        //此行注释掉
proxy_pass http://192.168.184.141/;   141后面的"/"与location后面的"/"保持一致,这里把客户端的请求都代理至141服务器上
index index.html index.htm;

}

6、 # systemctl reload nginx   //重新加载nginx

 

7、查看后端web服务器的访问日志(即192.168.184.141)

# tail /var/log/nginx/access.log   //可以看出是反向代理服务器代替用户请求的


下面在后端web服务器192.168.184.141上添加另外一个web页面文件

在web server:192.168.184.141上操作

# mkdir /var/www/html/bbs

# vim /var/www/html/bbs/index.html

<h1>Web server on bbs:192.168.184.141</h1> 

在nginx反向代理服务器上操作即142,只把bbs代理到客户端去

# vim /etc/nginx/conf.d/default.conf

location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
}
location /bbs/ {
    proxy_pass http://192.168.184.141/bbs/;
}

# systemctl reload nginx

    

location /forum/ {    //把这里的bbs改为forum,依然会代理到后端服务器
    proxy_pass http://192.168.184.141/bbs/;
}

查看后端服务器的日志(即192.168.184.141的日志)

# tail /var/log/nginx/access.log    //请求的是bbs,即映射至bbs

这里在代理服务器142上再做修改,如下

location /forum/ {    
    proxy_pass http://192.168.184.141/;   //这里把上面的bbs去掉,141后面的/表示根路径
}


第一个location例外

对匹配模式进行模拟

location ~* .(jpg|png|gif)$ {    //如果使用正则表达式向后匹配,后面的uri(即.(jpg|png|gif)$)并不是真正意义上的URL,它只是一个模式,所以是无                                      法向后映射的,但是模式匹配到的内容都会原封不动的补在http://192.168.184.141后面

    proxy_pass http://192.168.184.141;  //用户请求url只要以.(jpg|png|gif)结尾的都代理至后端服务器

}

在后端服务器141上/var/www/html目录下添加一个图片


下面对前后端做映射,即在后端服务器上把图片放到某个目录里面而不是放到根上

1、在后端服务器141上进行设置

# mkdir /var/www/html/images

# mv 1.jpg images/

匹配的是location .jpg结尾的文件,于是就把整个路径192.168.184.141/images/1.jpg送到后端服务器去了

proxy_pass http://192.168.184.141/images/; //这里是错误的,因为这里是模式匹配,后端服务器就不能再跟上URL了


第二个location例外

如果有location有URL重写的话,会使用重写后的结果像后端代理


示例

$host        记录的是客户端发送的请求报文中的首部的值
$remote_addr 记录是客户端的IP地址

Syntax: proxy_set_header field value;                                                                                                            
Default:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: httpserverlocation

# vim /etc/nginx/conf.d/default.conf   //在反向代理服务器142上进行设置

 location /forum/ {
    proxy_pass http://192.168.184.140/;
    proxy_set_header Host $host;           
    proxy_set_header X-Real-IP $remote_addr;   //无论客户端请求的是什么,都把请求者即客户端的IP赋予给X-Real-IP这个首部值
} 
location ~* .(jpg|png|gif)$ { proxy_pass http://192.168.184.140; proxy_set_header X-Real-IP $remote_addr; }

这是请求是成功的

但是请求的IP记录的依然是代理服务器

下面就要配置后端web服务器(140)记录的请求IP是客户端IP  注意。这里更换了后台web服务器,把nginx更换为了apache

# vim /etc/httpd/conf/httpd.conf 

LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

把第一行中改为

LogFormat "%{X-Real-IP}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
%{X-Real-IP}i   X-Real-IP某一个指定首部的值   i是固定格式

# service httpd reload

# tail /var/log/httpd/access_log    //查看后端服务器140的web访问日志

 

或者用192.168.186.141客户端进行访问

# curl http://192.168.184.142/forum/

<h1>Web Server on 192.168.184.140</h1>

在查看后端服务器140的访问日志


代理缓存的各种功能

下面介绍proxy_cache代理缓存,nginx缓存很独特,首先缓存是键值存储,键(即URL)是存放在内存中,值是存放在磁盘中的。

存放格式:在proxy服务器的内存中找一段区域以哈希编码的方式放所有的键,而每一个键(即URL)所指向的值是URL所对应的文件的内容,但这里缓存的不是内容,而是指向的在本地缓存空间中的文件路径。但这个路径是由特殊结构组织的,即在磁盘中做多个一级子目录,把URL对应值放在一级子目录下,最多有3级。

那么子目录如何定义?

Syntax:

proxy_cache_path path [levels=levels] [use_temp_path=on|off]keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number[manager_sleep=time] [manager_threshold=time]   

            [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off[purger_files=number] [purger_sleep=time] [purger_threshold=time];                

                                                   

Default:
Context: http  //只能用在http段中

示例:

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;

/data/nginx/cache  缓存所在目录

levels=1:2    1表示每一个一级子目录的名字只能用一个字符, 2表示每一个二级字目录可以使用两个字符

/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c

c表示一级子目录 

29表示二级子目录 

b7f54b2df7773722d382f4809d65029c对应的文件名

 

在http段中定义完缓存后,可以在某个server中调用缓存,如何调用?

Syntax:proxy_cache zone | off;  //off表示关闭缓存
Default:proxy_cache off;    

Context:httpserverlocation   //使用proxy指令在http、server、location中调用缓存

上面的zone是指在使用proxy_cache_path定义时,有keys_zone=name:size,表示在内存空间中找size空间并取名为name当作键存储的位置,

proxy_cache_path  path(磁盘上存内容的位置)  [levels=levels](按照这种结构进行组织) keys_zone=name:size(内存中存键的)   

proxy_cache_path可以定义多组,不同的server中可以调换不同cache,不同的server中也可以调换相同的cache。

使用什么方法是启用缓存

Syntax: proxy_cache_methods GET | HEAD | POST ...;   表示客户端在使用什么方法请求资源时才使用缓存                                                      
Default:
proxy_cache_methods GET HEAD;              通常只给GET和HEAD方法才缓存,这是默认,所以一般不用定义
Context: httpserverlocation

某一个请求被响应多少次才进行缓存

Syntax: proxy_cache_min_uses number;                          
Default:
proxy_cache_min_uses 1;  这里默认是1次                                                                                                              
Context: httpserverlocation

如何管理缓存空间中的缓存条目的?

Syntax: proxy_cache_purge string ...;   修剪                                                                                                 
Default:
Context: httpserverlocation

This directive appeared in version 1.5.7.

定义哪种请求做缓存管理

Example configuration:

proxy_cache_path /data/nginx/cache keys_zone=cache_zone:10m;

map $request_method $purge_method {       //把$request_method映射成$purge_method
    PURGE   1;
    default 0;
}

server {
    ...
    location / {
        proxy_pass http://backend;
        proxy_cache cache_zone;   //管理缓存空间中的缓存条目的
        proxy_cache_key $uri;
        proxy_cache_purge $purge_method;  //把proxy_cache_purge后面对应的方法映射为$purge_method
    }
}

purge方法的功能:

一旦在nginx提供缓存的话,那么在缓存有效期到达之前是不会失效的。当内容被缓存下来后,nginx在接收用户的请求后,如果本地有缓存服务器,代理服务器是不会将用户请求发送到后端的web服务器的,而是检查本地的缓存服务器,那么如果缓存服务器中的内容与用户的请求相匹配,代理服务器就不会再把请求发到后端服务器了。

那么有一个问题,在缓存服务器中的缓存内容失效之前,后端web服务器中相同的内容被修改了,此时用户请求此内容时,只能接收到缓存服务器的缓存内容,而无法获得后端服务器已经更新的内容。

解决办法:可以手动模拟对请求进行操作,即请求什么内容就把缓存中请求的内容删除,这是特殊请求,这种请求方法就叫缓存修剪方法。前提时你知道后端服务器已经更新,缓存服务器的内容还在有效期内。这时就可以发起修剪方法,一旦内容在缓存中被命中,即便没过期也会被清理掉。cache manager只能清理过期的缓存或者缓存满了。

这种机制叫做purge机制,要做权限限定

proxy_cache_revalidate:  是否对过期缓存做重新校验

Syntax: proxy_cache_revalidate on | off;                                                                                                         
Default:
proxy_cache_revalidate off;
Context: httpserverlocation

如果本地的缓存过期了,cache manager有可能把过期缓存删除也有可能没有来得及删除。如果没有删除,代理检查缓存时,发现有缓存但是是过期的,这是代理就会向后端服务器发出询问,查询后端服务器与当前缓存服务器的内容是否相同,即后端服务器上的内容是否更新,没有没有更新,那么缓存服务器上的内容一样是可用的,那么就只需要更新一下缓存上内容的过期时间继续使用,不需要再向后端服务器请求了。

proxy_cache_use_stale 

Syntax: proxy_cache_use_stale error | timeout | invalid_header | updating |http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429off ...;             
Default:
proxy_cache_use_stale off;
Context: httpserverlocation

当客户端的请求过来时,代理服务器发现缓存是过期的,但是后端服务器是宕机或者无法取得联系时,这时候该如何。

error|timeout|invalid_header|updating|http_500|http_502|http_503|http_504|http_403|http_404|http_429   表示在哪种场景中使用过期缓存

响应就由proxy_cache_use_stale定义了

proxy_cache_valid   自定义缓存时间

Syntax: proxy_cache_valid [code ...] time;                                                                                                        
Default:
Context: httpserverlocation

使用缓存时,在缓存服务器上的缓存时间是由后端服务器定义的,但也可以自己定义缓存时间

例子:这里是按照响应码来定义缓存时间的

proxy_cache_valid 200 302 10m;

proxy_cache_valid 404 1m;

proxy_connect_timeout:指代理服务器和后端服务器链接的时间,如果链接超时就是超时时长,超时后就会产生proxy_cache_use_stale 

proxy_hide_header:设定发给客户端的请求报文需要隐藏首部(代理服务器从后端服务器取到报文后需要在代理服务器构建报文发送到客户端,在构建内容相应给客户端时,不                     打算发送给客户端哪个首部)

proxy_read_timeout

Syntax: proxy_read_timeout time;                                                                                                               
Default:
proxy_read_timeout 60s;
Context: httpserverlocation

下面是cache生效的示例 

1、首先在代理服务(192.168.184.142)上修改配置:

不能在/etc/nginx/conf.d/default.conf文件中定义,因为此文件对应的是server端

跟缓存相关的都应该在/etc/nginx/nginx.conf文件的http段中定义

# vim /etc/nginx/nginx.conf 

proxy_cache_path /cache/nginx/ levels=1:1 keys_zone=mycache:32m;

//定义缓存路径-->/cache/nginx,但是这个目录的属主属组必须是nginx,因为运行worker进程的用户是nginx,如果是其他用户,那么这个用户必须是运行worker进    程的身份,

//levels=1:1  定义目录个数,第一个1是定义一级目录的个数只能使用一个字符,:后面的功能一样,1:1:1表示有3级子目录,每级目录有个多少用字符来定义

//keys_zone=mycache:32m  内存空间的名字是mycache,大小是32m

//inactive=time是指非活动期限,是指一个缓存最后一次被使用之后,多长时间再也没有被使用后,这段时间就叫非活动期限

# mkdir /cache/nginx -pv

# chown -R nginx:nginx /cache/nginx/   //更改属主数组

以上缓存就定义好了,但是要想生效还需要被调用

2、下面修改代理服务器(142)的server端 

# vim /etc/nginx/conf.d/default.conf

location /forum/ {   //这里在location中定义,(如果在server中定义,在后端取得的内容都可以缓存下来)
        proxy_cache mycache;   //后跟缓存空间的名字,多个location可以使用同一个缓存,因为之前定义的cache是定义在http段,所有server都可用
        proxy_cache_valid 200 1d;   //定义响应码为200的缓存是1天
        proxy_cache_valid 301 302 10m;  //同上
        proxy_cache_valid any 1m;    //除了上面两个定义的响应码外其他响应码都缓存1分钟
        proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;   //定义在哪些场景使用过期缓存,比如error、timeout等
        proxy_pass http://192.168.184.140/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }   

    location ~* .(jpg|png|gif)$ {
        proxy_cache mycache;
        proxy_cache_valid 200 1d; 
        proxy_cache_valid 301 302 10m;
        proxy_cache_valid any 1m; 
        proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
        proxy_pass http://192.168.184.140;
        proxy_set_header X-Real-IP $remote_addr;
    }   

# systemctl reload nginx

# ls /cache/nginx/   //此时查看缓存目录是没有任何信息的

如果在页面进行访问后,就可以看到此目录下有目录

http://192.168.184.142/forum/

# ls /cache/nginx/

/cache/nginx/0/0   //第一个0是一级字符,第二个0是二级字符

07af02629e00e0536ded660a69aeac00   //字符串是缓存条目,有了缓存条目后,相同的请求的后续内容都是在缓存中返回,

 

下面把后端服务器中的页面文件做一下修改,这里是在后端服务器(192.168.184.140)

# vim /var/www/html/index.html 

<h1>New Cache Web Server on 192.168.184.140</h1>

此时再次请求时,仍然是上面的结果,不会是新修改的web页面

如果想更新网页最暴力最简单的办法就是手动删除缓存条目

# rm -rf 0/0/07af02629e00e0536ded660a69aeac00   //注意此时是在/cache/nginx目录下

http://www.magedu.com  

http://mysql.magedu.com

Upstream    

http://nginx.org/en/docs/http/ngx_http_upstream_module.html

ngx_http_upstream_module模块用于定义可由proxy_pass, fastcgi_pass, uwsgi_pass, scgi_passmemcached_pa​​ss和 grpc_pass指令引用的服务器组

upstream只能定义在http中,不能用在server中

示例:    
location /forum/ { proxy_cache mycache; proxy_cache_valid 200 1d; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://192.168.184.140/; //proxy_pass后只可以跟一个主机,而upstream的功用就在于可以把多个主机做成一个组, proxy_set_header Host $host; //而后在proxy_pass后面跟上这个组的名字 proxy_set_header X-Real-IP $remote_addr; }

Syntax: upstream name { ... }                                                                                                           
Default:
Context: http   //只能定义在http中
upstream backend {   在upstream中定义一个组的时候,内部用server指令,每一个server用来标识后端服务器
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;   //多个server后端服务器的端口可以不一样
    server unix:/tmp/backend3;   //调用路径也可以不同

    server backup1.example.com  backup;
}
用法:
Syntax: server address [parameters];                                                                       
Default:
Context: upstream

示例:

两台nginx后端服务器,192.168.184.140和192.168.184.141,为了演示负载均衡的效果,需要把前面在代理服务器即142上配置的/etc/nginx/conf.d/default.conf设置的缓存需要取消。140和141服务器都需要安装好web页面

1、首先在代理服务器上编辑全局配置文件/etc/nginx/nginx.conf,在http的上下文中context进行编辑,定义后端服务器组upservers

http {
    include       /etc/nginx/mime.types;
    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  /var/log/nginx/access.log  main;
    upstream upservers {       //这里upservers是服务器组名
        server 192.168.184.140;   //利用server指令定义服务器,注意这里不能加http://
        server 192.168.184.141;
    }   
         
    sendfile        on; 
    #tcp_nopush     on; 

    keepalive_timeout  65; 

    include /etc/nginx/conf.d/*.conf;
}

2、编辑/etc/nginx/conf.d/default.conf文件,对应的location调用时,proxy_pass指定后端服务器组名

  location /forum/ {
        proxy_cache mycache;
        #proxy_cache_valid 200 1d; 
        #proxy_cache_valid 301 302 10m;
        #proxy_cache_valid any 1m; 
        #proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
        proxy_pass http://upservers/;   //这里upservers后面的斜线要与forum后面的斜线保持一致
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }   

    location ~* .(jpg|png|gif)$ {
        #proxy_cache mycache;
        #proxy_cache_valid 200 1d; 
        #proxy_cache_valid 301 302 10m;
        #proxy_cache_valid any 1m; 
        #proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
        proxy_pass http://upservers;   //这里就upservers后面的斜线就不能加,因为location是正则表达式匹配
        proxy_set_header X-Real-IP $remote_addr;
    }   



在server上定义权重

改变141服务器的默认权重,这里是在代理服务器142的http段配置

# vim /etc/nginx/nginx.conf

upstream upservers {
        server 192.168.184.140 weight=2;  
        server 192.168.184.141;
    }   

# systemctl reload nginx

实现ip_hash算法

Syntax: ip_hash;                                                                                           
Default:
Context: upstream

upstream backend { ip_hash; //只需在各server上加一个ip_hash;,这就相当于LVS的SH算法 server backend1.example.com; server backend2.example.com; server backend3.example.com down; server backend4.example.com; }
例子:
upstream upservers {
ip_hash; //这里根据上面的演示添加了ip_hash; server 192.168.184.140 weight=2; server 192.168.184.141; }
# systemctl reload nginx //重新加载nginx
此时在浏览器中访问http://192.168.184.142/forum/时,代理服务器会把所有请求发送到同一个后端服务器

server address [parameters];   parameters的参数

max_fails=number  做健康状态检查,一旦检查的错误次数到达设定次数,就标记为失败

fail_timeout=time  每次检查失败的次数是多长

示例

在代理服务器的http段进行配置

# vim /etc/nginx/nginx.conf

    upstream upservers {
        server 192.168.184.140 max_fails=2 fail_timeout=1;   2表示2次,1表示1秒
        server 192.168.184.141 max_fails=2 fail_timeout=1;
    }  

# systemctl reload nginx

此时以142为代理服务器,140和141是后端服务器,实现负载均衡,算法是rr,是没有问题的

下面让140节点故障,此时就只有141可以工作,并不报错

在140服务器上启动nginx服务,那么在浏览器中http://192.168.184.142/forum/访问,140会被自动上线,这就是max_fails和fail_timeout两项功能指定的后端real server健康状态检擦的功能。

后端服务器需要版本升级,但又不支持平滑升级,就可以先下线一个升级,再下线第二个升级,一次类推。

示例:backup是当作备用server,只要有正常的server,这个就不用,此时就只有140上线

    upstream upservers {
        server 192.168.184.140 max_fails=2 fail_timeout=1;
        server 192.168.184.141 max_fails=2 fail_timeout=1 backup;   //标记为备用
    }   

此时把140下线,141就有效了,这样的好处就在于当所有的后端server都下线,那么bachup就可以当作sorry页面

原文地址:https://www.cnblogs.com/hanshanxiaoheshang/p/9941007.html