目录

1、nginx反向代理及负载均衡

1.1 nginx反向代理实战

1、什么是代理服务器

2、为什么要使用代理服务器

3、反向代理 VS 正向代理

4、Nginx正向代理实战

5、Nginx反向代理实战

1.2 nginx负载均衡实战

1.3 nginx反向代理案例

1.3.1 反向代理多虚拟主机节点服务器企业案例

1.3.2 经过反向代理后的节点服务器记录用户IP企业案例

1.3.3 根据URL中的目录地址实现代理转发案例

1.3.4 根据客户端的设备(user_agent)转发

1.3.5 根据扩展名转发的应用场景


1、nginx反向代理及负载均衡

1.1 nginx反向代理实战

1、什么是代理服务器

        代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬盘中,再发送给客户机。

2、为什么要使用代理服务器

  • 提高访问速度
    • 由于目标主机返回的数据会存放在代理服务器的硬盘中,因此下一次客户再访问相同的站点数据时,会直接从代理服务器的硬盘中读取,起到了缓存的作用,尤其对于热门站点能明显提高请求速度。
  • 防火墙作用
    • 由于所有的客户机请求都必须通过代理服务器访问远程站点,因此可在代理服务器上设限,过滤某些不安全信息。
  • 通过代理服务器访问不能访问的目标站点
    • 互联网上有许多开发的代理服务器,客户机在访问受限时,可通过不受限的代理服务器访问目标站点

3、反向代理 VS 正向代理

正向代理

        正向代理,架设在客户机与目标主机之间,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。

反向代理

        反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。

4、Nginx正向代理实战

nginx正向代理的功能

1.由于nginx正向代理的功能指令较少,只需要进行简单的配置即可

server {  
   resolver 114.114.114.114;       #指定DNS服务器IP地址  
   listen 8080;  
   location / {  
       proxy_pass http://$http_host$request_uri;     #设定代理服务器的协议和地址  
  }  
} 

以上的配置只能访问80 端口的网站,而不能访问https443端口的网站,现在的网站基本上都是https的要解决技能访问http80端口也能访问https443端口的网站,需要置两个SERVER节点,一个处理HTTP转发,另一个处理HTTPS转发,而客户端都通过HTTP来访问代理,通过访问代理不同的端口,来区分HTTP和HTTPS请求。

由于原生 nginx 只支持 http 正向代理,为了 nginx 支持 https 正向代理,可以打
ngx_http_proxy_connect_module 补丁+ ssl 模块支持。

添加 https 代理模块

这里需要重新编译 nginx,需要查看当前 nginx 的版本和编译选项,然后去官网下载同版本的 nginx 源码进行重新编译

/usr/local/nginx/sbin/nginx -V
wget http://nginx.org/download/nginx-1.15.12.tar.gz
tar -zxvf nginx-1.15.12.tar.gz

下载模块 ngx_http_proxy_connect_module

git clone https://github.com/chobits/ngx_http_proxy_connect_module

打补丁,对 nginx 源码修改,这一步很重要,不然后面的 make 过不去

patch -d /root/nginx-1.15.12/ -p 1 <
/root/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite

在原有配置后追加模块,make 后注意不要 instal

cd /root/nginx-1.15.12/
./configure --with-http_stub_status_module --with-http_ssl_module --with-file-
aio --with-http_realip_module --add-module=/root/ngx_http_proxy_connect_module/
make
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp /root/nginx-1.15.12/objs/nginx /usr/local/nginx/sbin/

配置文件如下,然后启动服务

# 正向代理上网
server {
   listen       38080;

   # 解析域名
   resolver     8.8.8.8;

   # ngx_http_proxy_connect_module
  proxy_connect;
   proxy_connect_allow            443 563;
   proxy_connect_connect_timeout 10s;
   proxy_connect_read_timeout     10s;
   proxy_connect_send_timeout     10s;

   location / {
       proxy_pass $scheme://$http_host$request_uri;
  }
}

5、Nginx反向代理实战

        现在许多大型web网站都用到反向代理。除了可以防止外网对内网服务器的恶性攻击、缓存以减少服务器的压力和访问安全控制之外,还可以进行负载均衡,将用户请求分配给多个服务器。

环境准备

        硬件准备:准备4台VM虚拟机

HOSTNAMEIP说明
lb01192.168.150.11Nginx主负载均衡器
lb02192.168.150.12Nginx副负载均衡器
web01192.168.150.13Web01服务器
web02192.168.150.14Web02服务器

软件准备

        系统:CentOS7.x x86_64
        软件:nginx-1.10.0-1.el7.ngx.x86_64.rpm

1> 安装nginx。
        以下操作在4台服务器执行。

yum install nginx-1.10.0-1.el7.ngx.x86_64.rpm

2> 配置用于测试的Web服务(以下操作在两台web服务器)。
        配置虚拟主机

# cd /etc/nginx/conf.d/
# mv default.conf{,.bak}
# cat vhost.conf

server {
  listen       80;
  server_name bbs.yunjisuan.com;
  location / {
      root   /usr/share/nginx/html/bbs;
      index index.html index.htm;
  }
access_log /usr/share/nginx/html/bbs/logs/access_bbs.log main;
}
server {
  listen       80;
  server_name www.yunjisuan.com;
  location / {
      root   /usr/share/nginx/html/www;
      index index.html index.htm;
  }
access_log /usr/share/nginx/html/www/logs/access_www.log main;
}
  • 指令说明:proxy_pass
  • 语法:proxy_pass URL
  • 默认值:no
  • 使用字段:location, location中的if字段
  • 这个指令设置被代理服务器的地址和被映射的URI,地址可以使用主机名或IP加端口号的形式,例如:proxy_pass http://localhost:8000/uri/;

3> 配置用于测试的Web服务
        以下操作在两台web服务器。
准备测试页面

mkdir -p /usr/share/nginx/html/{www,bbs}/logs
echo "`hostname -I `www" > /usr/share/nginx/html/www/index.html
echo "`hostname -I `bbs" > /usr/share/nginx/html/bbs/index.html

启动服务测试:

systemctl start nginx
systemctl enable nginx

[root@lb01 ~]# curl -H host:bbs.yunjisuan.com 192.168.150.13
192.168.150.13 bbs
[root@lb01 ~]# curl -H host:bbs.yunjisuan.com 192.168.150.14
192.168.150.14 bbs
[root@lb01 ~]# curl -H host:www.yunjisuan.com 192.168.150.13
192.168.150.13 www
[root@lb01 ~]# curl -H host:www.yunjisuan.com 192.168.150.14
192.168.150.14 www

1.2 nginx负载均衡实战

搭建负载均衡服务的需求如下:

1 ) 把单台计算机无法承受的大规模并发访问或数据流量分担到多台节点设备上,分别进行处理, 减少用户等待响应的时间, 提升用户体验。

2 ) 单个重负载的运算分担到多台节点设备上做并行处理, 每个节点设备处理结束后, 将结果汇总, 返回给用户, 系统处理能力得到大幅度提高。

3 ) 7 x 24 小时的服务保证, 任意一个或多个有限后面节点设备宕机, 不能影响业务。
在负载均衡集群中, 同组集群的所有计算机节点都应该提供相同的服务。 集群负载均衡器会截获所有对该服务的入站请求。 然后将这些请求尽可能地平均地分配在所有集群节点上。

实现 Nginx 负载均衡的组件说明

Nginx http 功能模块模块说明
ngx_http_proxy_moduleproxy 代理模块, 用于把请求后拋给服务器节点或 upstream 服
务器池
ngx_http_upstream_module负载均衡模块, 可以实现网站的负载均衡功能及节点的健康检査

配置简单的负载均衡
        以下操作在lb01

upstream www_server_pools {
   server 192.168.150.13:80 weight=1;
   server 192.168.150.14:80 weight=1;
  }

server {
   listen       80;
   #server_name localhost;
   server_name www.yunjisuan.com;
   
   #charset koi8-r;
   #access_log /var/log/nginx/log/host.access.log main;

   location / {
    #   root   /usr/share/nginx/html;
    #   index index.html index.htm;
    # 访问www.yunjisuan.com,请求发送给www_server_pools里面的节点
      proxy_pass http://www_server_pools;
  }
  ...

#这里定义Web服务器池,包含了13,14两个Web节点

重启服务

[root@lb01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 ~]# systemctl restart nginx

配置hosts解析并测试

[root@lb01 ~]# tail -1 /etc/hosts
192.168.150.11 www.yunjisuan.com

[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.13 bbs
192.168.150.14 bbs
192.168.150.13 bbs
192.168.150.14 bbs

测试结果是bbs页面,而不是www,在后面介绍如何解决。

从上面的测试结果可以看出来。两个Web节点按照1:1的比例被访问。
下面宕掉任意一个Web节点,看看测试结果如何,测试如下:

[root@web02 ~]# systemctl stop nginx
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.13 bbs
192.168.150.13 bbs
192.168.150.13 bbs
192.168.150.13 bbs

节点恢复正常后,再次测试:

[root@web02 ~]# systemctl start nginx
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.14 bbs
192.168.150.13 bbs
192.168.150.14 bbs
192.168.150.13 bbs

Nginx中常用模块说明

节点恢复正常后,再次测试:

[root@web02 ~]# systemctl start nginx
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.14 bbs
192.168.150.13 bbs
192.168.150.14 bbs
192.168.150.13 bbs

配置hosts解析并测试

[root@lb01 ~]# tail -1 /etc/hosts
192.168.150.11 www.yunjisuan.com
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.13 bbs
192.168.150.14 bbs
192.168.150.13 bbs
192.168.150.14 bbs

测试结果是bbs页面,而不是www,在后面介绍如何解决。

1> Nginx upstream模块

        Nginx的负载均衡功能依赖于ngx_http_upsteam_module模块,所支持的代理方式包括
proxy_pass,fastcgi_pass,memcached_pass等,新版Nginx软件支持的方式有所增加。本文主要讲解proxy_pass代理方式。

        ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为“proxy_pass http:// www_server_pools”,其中www_server_pools就是一个Upstream节点服务器组名字。ngx_http_upstream_module模块官方地址为http://nginx.org/en/docs/http/ngx_http_upstrea m_module.html。

示例1:基本的upstream配置案例

upstream www_server_pools {
#upstream是关键字必须有,后面的www_server_pools为一个Upstream集群组的名字,可以自己起名,
调用时就用这个名字

    server 192.168.0.223:80 weight=5;
    server 192.168.0.224:80 weight=10;
    server 192.168.0.225:80 weight=15;
#server关键字是固定的,后面可以接域名(门户会用)或IP。如果不指定端口,默认是80端口。weight代
表权重,数值越大被分配的请求越多,结尾有分号。
}

示例2:较完整的upstream配置案例

upstream www_server_pools {
server 192.168.0.223;   #这行标签和下行是等价的
server 192.168.0.224:80 weight=1 max_fails=1 fail_timeout=10s;       
#这行标签和上一行是等价的,此行多余的部分就是默认配置,不写也可以。

server 192.168.0.225:80 weight=1 max_fails=2 fail_timeout=20s backup;

# server最后面可以加很多参数,具体参数作用看下文的表格
}

示例3:使用域名及socket的upstream配置案例

upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;   #域名加端口。转发到后端的指定端口上
server unix:/tmp/backend3;  #指定socket文件

#提示:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析。
server 192.168.0.223;
server 192.168.0.224:8080;
server backup1.example.com:8080 backup;
#备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样
server backup2.example.com:8080 backup;
}

upstream参数

模块内参数参数说明
server 10.0.10.8:80负载均衡后面的RS配置,可以是IP或域名,如果端口不写,默认是80端口。高并发场景下, IP可换成域名,通过 DNS做负载均衡。
weigth=1代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。
max_fails=3Nginx尝试连接后端主机失败的次数,这个值是配合proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream 这三个参数来使用的。当nginx接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503、 Max_fails的默认值是1 ;企业场景下建议2-3次。如京东1次,蓝汛10次,根据业务需求去配置
fail_timeout=10s在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s ;如果max_fails是5 ,它就检测5次,如果5次都是502,那么,它就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载 Nginx配置的情况下,每隔10s都只检查一次。常规业务2~3秒比较合理,比如京东3秒,蓝汛3秒,可根据业务需求去配置。
backup热备配置(RS节点的高可用),当前面激活的RS都失败后会自动启用热备RS这标志看这个服务器作为备份服务器,若主服务器全部宕机了,就会向它转发请求。注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
down这标志着服务器永远不可用,这个参数可配合ip_hash使用;类似与注释。

模块调度算法
调度算法一般分为两类:

  • 第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr,wrr,ip_hash等都属于静态调度算法。
  • 第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响应时间短的优先获得请求。例如:least_conn,fair等都属于动态调度算法。

常用调动算法

        ①. 定义轮询调度算法-rr-默认调度算法

        ②. 定义权重调度算法-wrr

        ③. 定义静态调度算法-ip_hash
             该调度算法可以解决动态网页的session共享问题

        ④. 定义最小的连接数-least_conn

2> http_proxy_module模块

proxy_pass指令

        proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过proxy_pass抛给定义好的upstream节点池。该指令官方地址:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

示例1:将匹配URI为name的请求抛给http://127.0.0.1/remote/.

location /name/ {
    proxy_pass http://127.0.0.1/remote/;
}

示例2:将匹配URI为some/path的请求抛给http://127.0.0.1

location /some/path/ {
    proxy_pass http://127.0.0.1;
}

示例3:将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1

location /name/ {
    rewrite /name/( [^/]+ ) /username=$1 break;
    proxy_pass http://127.0.0.1;
}

nginx负载均衡相关重要参数

Nginx反向代理重要参敎解释说明
proxy_pass http://server_pools;通过proxy_pass功能把用户的清求转向到反向代理定义的upstream服务器池
proxy_set_header Host $host在代理向后端服务器发送的 http请求头中加入 host字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置
proxy_set_header X-Forwarded-For $remote_addr;在代理向后端服务器发送的 http请求头中加入 X-Forward-For字段信息,用于后端服务器程序、日志等接收记录真实用户的 IP ,而不是代理服务器的IP这是反向代理时,节点服务器获取用户真实 IP的必要功能配置

http proxy 模块相关参数说明

http proxy模块相关参数说明
proxy_set_header设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址
client_body_buffer_size用于指定客户端请求主体缓冲区大小
proxy_connect_timeout表示反向代理后端节点服务器连接的超时时间,即发起握手等候响应的超时时间
proxy_send_timeout表示代理后端服务器的数据回传时间,即在规定时间内后端服务器必须传完所有数据,否则nginx将断开这个连接
proxy_read_timeout设置nginx从代理的后端服务器获取信息的时间,表示连接建立成功后,nginx等待后端服务器的响应时间,其实是nginx已经进入后端的排队之中等候处理的时间
proxy_buffer_size设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小
proxy_buffers设置缓冲区的数量和大小,nginx从代理的后端服务器获取的响应信息,会设置到缓冲区
proxy_busy_buffers_size用于设置相同很忙时可以使用的proxy_buffers大小,官方推荐的大小为 proxy_buffers * 2
proxy_trmp_file_write_size指定proxy缓存临时文件的大小

3> upstream模块语法

示例3:使用域名及socket的upstream配置案例

upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;   #域名加端口。转发到后端的指定端口上
server unix:/tmp/backend3;  #指定socket文件

#提示:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析。
server 192.168.0.223;
server 192.168.0.224:8080;
server backup1.example.com:8080 backup;
#备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样
server backup2.example.com:8080 backup;
}

故障解决:

nginx反向代理报错400
根据400报错以及对http协议的原理了解得知是因为请求头的原因,原因是因为upstream后面的名称有下划线使得代理无法识别

1.3 nginx反向代理案例

1.3.1 反向代理多虚拟主机节点服务器企业案例

proxy_set_header host $host;

在代理向后端服务器发送的http请求头中加入host字段信息后,若后端服务器配置有多个虚拟主机,它就可以识别代理的是哪个虚拟主机。

上一节代理的结果不对,究其原因是当用户访问域名时确实是携带了www.yunjisuan.com主机头请求Nginx反向代理服务器,但是反向代理向下面节点重新发起请求时,默认并没有在请求头里告诉节点服务器要找哪台虚拟主机,所以,Web节点服务器接收到请求后发现没有主机头信息,因此,就把节点服务器的第一个虚拟主机发给了反向代理了,所以结果是bbs

在代理向后端服务器发送的http请求头中加入host字段信息后,若后端服务器配置有多个虚拟主机,它就可以识别代理的是哪个虚拟主机。

[root@lb01 ~]# cat /etc/nginx/conf.d/vhost.conf
server {
    listen       80;
    server_name www.yunjisuan.com;
    location / {
        proxy_pass http://www_server_pools;
        proxy_set_header Host $host;
    }
}
server {
    listen       80;
    server_name bbs.yunjisuan.com;
    location / {
        proxy_pass http://www_server_pools;
        proxy_set_header Host $host;
    }
}

重启代理测试:

[root@lb01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 ~]# systemctl restart nginx

[root@lb01 ~]# tail -1 /etc/hosts
192.168.150.11 www.yunjisuan.com bbs.yunjisuan.com
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://bbs.yunjisuan.com; done
192.168.150.14 bbs
192.168.150.13 bbs
192.168.150.14 bbs
192.168.150.13 bbs
[root@lb01 ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
192.168.150.14 www
192.168.150.13 www
192.168.150.14 www
192.168.150.13 www

1.3.2 经过反向代理后的节点服务器记录用户IP企业案例

案例背景:
        完成了反向代理WWW服务后,发现一个问题,节点服务器对应的WWW虚拟主机的访问日志的第一个字段记录的并不是客户端的IP,而是反向代理服务器的IP,最后一个字段也是“-”!

[root@web01 ~]# tail -2 /usr/share/nginx/html/www/logs/access_www.log
192.168.150.11 - - [06/Nov/2019:12:31:04 +0800] "GET / HTTP/1.0" 200 19 "-"
"curl/7.29.0" "-"
192.168.150.11 - - [06/Nov/2019:12:31:05 +0800] "GET / HTTP/1.0" 200 19 "-"
"curl/7.29.0" "-"

Web01节点服务器对应的WWW虚拟主机的访问日志的第一个字段记录的并不是客户端的IP而是反向代理服务器本身的IP(192.168.150.1),最后一个字段也是一个“-”,那么如何解决这个问题?其实很简单,同样是增加如下一行参数:

proxy_set_header X-Forwarded-For $remote_addr;
#这是反向代理时,节点服务器获取用户真实IP的必要功能配置

1> 代理服务器配置添加

proxy_set_header X-Forwarded-For $remote_addr;
#这是反向代理时,节点服务器获取用户真实IP的必要功能配置

2> 后端节点服务日志修改
“$http_x_forwarded_for”参数 记录真实IP,默认在末尾,如果希望在行首,可以替换掉$remote_addr变量

代理重启后客户端访问测试:

[root@web01 ~]# tail -2 /usr/share/nginx/html/www/logs/access_www.log
192.168.150.11 - - [06/Nov/2019:12:35:18 +0800] "GET / HTTP/1.0" 200 19 "-"
"curl/7.29.0" "192.168.150.15"
192.168.150.11 - - [06/Nov/2019:12:35:19 +0800] "GET / HTTP/1.0" 200 19 "-"
"curl/7.29.0" "192.168.150.15"

1.3.3 根据URL中的目录地址实现代理转发案例

案例背景:
        通过Nginx实现动静分离,即通过Nginx反向代理配置规则实现让动态资源和静态资源及其他业务分别由不同的服务器解析,以解决网站性能,安全,用户体验等重要问题。

        下图为企业常见的动静分离集群架构图,此架构图适合网站前端只使用同一个域名提供服务的场景,例如,用户访问的域名是www.yunjisuan.com,然后,当用户请求www.yunjisuan.com/upload/xx地址时候,代理会分配请求到上传服务器池处理数据;当用户请求www.yunjisuan.com/static/xx地址的时候,代理会分配请求到静态服务器池请求数据;当用户请求www.yunjisuan.com/xx地址的时候,即不包含上述指定的目录地址路径时,代理会分配请求到默认的动态服务器池请求数据(注意:上面的xx表示任意路径)。

当用户请求www.yunjisuan.com/upload/xx地址时,实现由upload上传服务器池处理请求。
当用户请求www.yunjisuan.com/static/xx地址时,实现由静态服务器池处理请求。
除此以外,对于其他访问请求,全都由默认的动态服务器池处理请求。

upstream模块服务器池的配置

#static_pools为静态服务器池,有一个服务器,地址为192.168.150.13,端口为80.
upstream static_pools {
    server 192.168.150.13:80 weght=1;
}

#upload_pools为上传服务器池,有一个服务器地址为192.168.150.14,端口为80.
upstream upload_pools {
    server 192.168.150.14:80 weight=1;
}

#default_pools为默认的服务器池,即动态服务器池,有一个服务器,地址为192.168.150.15,端口为80.
upstream default_pools {
    server 192.168.150.15:80 weight=1;
}
#提示:需要增加一台测试Web节点Web03(ip:192.168.150.15),配置与Web01,Web02一样。

以location方案实现

#将符合static的请求交给静态服务器池static_pools,配置如下:

location /static/ {
   proxy_pass http://static_pools;
   proxy_set_header X-Forwarded-For $remote_addr;
}

#将符合upload的请求交给上传服务器池upload_pools,配置如下:
location /upload/ {
   proxy_pass http://upload_pools;
   proxy_set_header X-Forwarded-For $remote_addr;
}

#不符合上述规则的请求,默认全部交给动态服务器池default_pools,配置如下:
location / {
   proxy_pass http://default_pools;
   proxy_set_header X-Forwarded-For $remote_addr;
}

准备测试数据:

[root@web01 ~]# cd /usr/share/nginx/html/
[root@web01 html]# mkdir static
[root@web01 html]# echo "static_pools" >> static/index.html

[root@web02 ~]# cd /usr/share/nginx/html/
[root@web02 html]# mkdir upload
[root@web02 html]# echo "upload_pools" >> upload/index.html

[root@web03 ~]# cd /usr/share/nginx/html/
[root@web03 html]# echo "default_pools" >> index.html

测试:

[root@lb02 ~]# tail -1 /etc/hosts
192.168.150.11 www.yunjisuan.com

[root@lb02 ~]# curl http://www.yunjisuan.com/upload/
upload_pools
[root@lb02 ~]# curl http://www.yunjisuan.com/static/
static_pools
[root@lb02 ~]# curl http://www.yunjisuan.com/
default_pools

根据URL目录地址转发的应用场景

        根据HTTP的URL进行转发的应用情况,被称为第7层(应用层)的负载均衡,而LVS的负载均衡一般用于TCP等的转发,因此被称为第4层(传输层)的负载均衡。

        在企业中,有时希望只用一个域名对外提供服务,不希望使用多个域名对应同一个产品业务,此时就需要在代理服务器上通过配置规则,使得匹配不同规则的请求会交给不同的服务器池处理。

        业务的域名没有拆分或者不希望拆分,但希望实现动静分离,多业务分离,这在前面已经讲解过案例了。

        不同的客户端设备(例如:手机和PC端)使用同一个域名访问同一个业务网站,就需要根据规则将不同设备的用户请求交给后端不同的服务器处理,以便得到最佳用户体验。

1.3.4 根据客户端的设备(user_agent)转发

在企业中,为了让不同的客户端设备用户访问有更好的体验,需要在后端架设不同服务器来满足不同的客户端访问,例如:移动客户端访问网站,就需要部署单独的移动服务器及程序,体验才能更好,而且移动端还分苹果,安卓,Ipad等,在传统的情况下,一般用下面的办法解决这个问题。

使用之前的环境。

location / {
if ($http_user_agent ~* "MSIE")
#如果请求的浏览器为微软IE浏览器(MSIE),则让请求由static_pools池处理
{
    proxy_pass http://static_pools;
}
if ($http_user_agent ~* "Chrome")
#如果请求的浏览器为谷歌浏览器(Chrome),则让请求由upload_pools池处理
{
    proxy_pass http://upload_pools;
}
proxy_pass http://default_pools;
proxy_set_header Host $host;
#其他客户端,由default_pools处理
}

测试:curl -A 指定访问类型

[root@lb01 conf.d]# curl -A MSIE -H host:www.yunjisuan.com 192.168.150.11
192.168.150.13 www
[root@lb01 conf.d]# curl -A Chrome -H host:www.yunjisuan.com 192.168.150.11
192.168.150.14 www
[root@lb01 conf.d]# curl -A xxx -H host:www.yunjisuan.com 192.168.150.11
default_pools

1.3.5 根据扩展名转发的应用场景

可根据扩展名实现资源的动静分离访问,如图片,视频等请求静态服务器池,PHP,JSP等请求动态服务器池。

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
proxy_pass http://static_pools;
include proxy.conf;

}

location ~ .*\.(php|php3|php5)$ {
proxy_pass http://dynamic_pools;
include proxy.conf

}

Nginx负载均衡检测节点状态

淘宝技术团队开发了一个Tengine(Nginx的分支)模块Nginx_upstream_check_module,用于提供主动式后端服务器健康检查。通过它可以检测后端realserver的健康状态,如果后端realserver不可用,则所有的请求就不会转发到该节点上。

Tengine原生支持这个模块,而Nginx则需要通过打补丁的方式将该模块添加到Nginx中。补丁下载地址:https://github.com/yaoweibin/nginx_upstream_check_module

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐