1.基于7层负载均衡实现不同场景的调度

1.1 基于 不同uri 请求调度至不同集群

44. Nginx负载均衡实战 - 图1

  • www.xxx.com/user,使用多端口方式(web01—->模拟web集群1)
    [root@web01 ~]# cat /etc/nginx/conf.d/agent.oldxu.com.conf
  1. server {
  2. listen 8080;
  3. server_name agent.oldxu.com;
  4. root /agent/8080;
  5. location / {
  6. index index.html;
  7. }
  8. }
  9. server {
  10. listen 8081;
  11. server_name agent.oldxu.com;
  12. root /agent/8081;
  13. location / {
  14. index index.html;
  15. }
  16. }

mkdir /agent/{8080,8081} -p
echo "user-8080" > /agent/8080/index.html
echo "user-8081" > /agent/8081/index.html
systemctl reload nginx

  • www.xxxxx.com/pass,使用多端口方式 (web2—->模拟web集群2)
    [root@web02 ~]# cat /etc/nginx/conf.d/agent.oldxu.com.conf ```bash server { listen 8082; server_name agent.oldxu.com; root /agent/8082;

    location / {

      index index.html;
    

    } }

server { listen 8083; server_name agent.oldxu.com; root /agent/8083;

location / {
    index index.html;
}

}

`mkdir /agent/{8082,8083} -p`<br />`echo "pass-80802" > /agent/8082/index.html`<br />`echo "pass-80803" > /agent/8083/index.html`<br />`systemctl reload nginx`


<a name="9c3413d2"></a>
#### 1.1.1使用负载均衡作为统一入口,根据用户请求的uri进行调度
[root[@lb01 ](/lb01) ~]# `cat /etc/nginx/conf.d/``proxy``_agent.oldxu.com.conf`

```bash
upstream  agent-user {
    server 172.16.1.7:8080;
    server 172.16.1.7:8081;
}
upstream agent-pass {
    server 172.16.1.8:8082;
    server 172.16.1.8:8083;
}

server {
    listen 80;
    server_name agent.oldxu.com;
    location /user { 
        #uri1
        proxy_pass http://agent-user/;
        include proxy_params;
    }
    #uri2
    location /pass {
        proxy_pass http://agent-pass/;
        include proxy_params;
    }
}

1.2 将来源的终端设备调度不同的页面

image.png

pc: pc端百度         手机:显示是手机端的百度

  • web01作为手机端
    [root@web01 ~]# cat /etc/nginx/conf.d/useragent.oldxu.com.conf
server {
    listen 80;
    server_name useragent.oldxu.com;
    root /useragent;

    location / {
        index index.html;
    }
}

[root@web01 ~]# mkdir /useragent
[root@web01 ~]# echo "Phone..." > /useragent/index.html
[root@web01 ~]# systemctl reload nginx

  • web02作为pc端
    [root@web02 ~]# cat /etc/nginx/conf.d/useragent.oldxu.com.conf
server {
    listen 80;
    server_name useragent.oldxu.com;
    root /useragent;

    location / {
        index index.html;
    }
}

[root@web02 ~]# mkdir /useragent
[root@web02 ~]# echo "PC..." > /useragent/index.html
[root@web02 ~]# systemctl reload nginx

1.2.1负载均衡判断设备,然后调度到不同的集群。

[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_useragent.oldxu.com.conf

upstream pc {
    server 172.16.1.8:80;
}

upstream sj {
    server 172.16.1.7:80;
}


server {
    listen 80;
    server_name useragent.oldxu.com;
    charset utf-8;

    location / {
        default_type text/html;  
        #默认不支持将文字 打印到浏览器,所以需要调整默认的类型

    proxy_pass http://pc;   #默认走PC
        include proxy_params;

#判断
if ( $http_user_agent ~* "android|iphone|ipad" ) {
            proxy_pass http://sj;
        }

#如果开发写的代码不支持某些浏览器,还可以直接在Nginx层面拒绝他比如:MSIE
    if ( $http_user_agent ~* "Firefox|MSIE" ) {
    return 200 "你当前使用的浏览器真棒!";
        }
    }
}

1.3 proxy_pass 添加 / 和不添加 / 有什么区别?

proxy_pass有两种常用的写法:
proxy_pass http://localhost:8080;
proxy_pass http://localhost:8080/;

带 / 和 不带 / 有什么区别呢?

  • 无 / 示例:
    location /user {
      proxy_pass http://172.16.1.7:80;
    }
    

    用户请求URL: /user/test/index.html 请求到达Nginx负载均衡: /user/test/index.html Nginx负载均衡到后端节点: /user/test/index.html

  • 带 / 示例:
    location /user {
      proxy_pass http://172.16.1.7:80/;
    }
    

    用户请求URL: /user/test/index.html 请求到达Nginx负载均衡: /user/test/index.html Nginx负载均衡到后端节点: /test/index.html

总结:
1.带 / 意味着Nginx会修改用户请求的URL,将location匹配的URL进行删除。
2.不带 / 意味着Nginx不会修改用户请求的URL,而是直接代理到后端应用服务器。

1.4 alias的用法

uer请求: xxx.xxx.com/static**
location如何找到对应的资源???

nginx指定文件路径有两种方式root和alias root与alias主要区别在于nginx如何解释location后面的uri. ——>> 这会使两者分别以不同的方式将请求映射到服务器文件上 简单说就是两者拼接文件路径的手段不一样。


  • 第一种方案:请求 python.com/static Nginx把请求解析映射为 —> /opt/pythonav/static/xxx.png

    server {
      listen 80;
      server_name  python.com;
    
    ...
    location /static {
          root /opt/pythonav/;
    }
    
  • 第二种方案:请求 python.com/static Nginx把请求解析映射为 —> /opt/pythonav/xxx/xx/static/xx.png

    ...
    location /static {
          alias /opt/pythonav/xxx/xx/static/;
    }
    
    1. 使用alias时,目录名后面一定要加”/“,不然会认为是个文件。
    2. alias在使用正则匹配时,location后uri中捕捉到要匹配的内容后,并在指定的alias规则内容处使用。
    3. alias只能位于location块中,而root的权限不限于location。

*3. 多级代理实现透传真实IP地址


image.png

客户端经过的所有代理都必须添加X-Forward-For头字段
( 其中某一个环节没有,那么就无法提取到真是的IP地址)
image.png

Nginx RealIP**模块来实现地址透传

10.0.0.1-->  client    ip.oldxu.com  -->    10.0.0.5(proxy-1)  -->  
10.0.0.7(proxy-2)  --> 10.0.0.8 --> web

抓包分析: image.png

  • proxy-1
    [root@lb01 ~]# cat /etc/nginx/conf.d/proxy_ip.oldxu.com.conf

    server {
      listen 80;
      server_name ip.oldxu.com;
    
      location / {
          proxy_pass http://10.0.0.7;
          proxy_set_header Host $http_host;
          proxy_set_header X-Real-IP  $remote_addr;    #没啥用,使用X-Forwarded-For 
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
    }
    
  • proxy-2

[root@web01 ~]# cat /etc/nginx/conf.d/proxy_ip.oldxu.com.conf

server {
    listen 80;
    server_name ip.oldxu.com;

    location / {
        proxy_pass http://10.0.0.8;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
  • web
    [root@web02 ~]# cat /etc/nginx/conf.d/ip.oldxu.com.conf

    server {
      listen 80;
      server_name ip.oldxu.com;
      root  /php;
    
      location /  {
          index index.php;
      }
    
      location ~ \.php$ {
          fastcgi_pass 127.0.0.1:9000;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include  fastcgi_params;
      }
    }
    

web站点内容
[root@web02 ~]# mkdir /php
[root@web02 ~]# cat /php/index.php

<?php
    $ip = getenv("HTTP_X_FORWARDED_FOR");
    echo "获取X_FORWARDED_FOR的真实IP地址是: $ip";
?>

通过最后日志发现: 10.0.0.7 - - [28/Apr/2020:15:06:09 +0800] “GET / HTTP/1.0” 200 “10.0.0.1, 10.0.0.5”

10.0.0.7 是web服务器上一层代理服务器 X-FORWARDED 第一个地址是真实IP,后面的全部都是经过的代理服务器地址 10.0.0.1 是真实的客户端地址,他后面的都是代理的地址

X-Forwarded-For提取真实IP的方式: 优点:一定能提取到真是的IP地址 缺点:必须所有经过的代理服务器都开启X-FORWARDED-FOR变量携带IP至后端

Nginx_RealIP模块:
10.0.0.1 —> client ip.oldxu.com
10.0.0.5 —> proxy-1
10.0.0.7 —> proxy-2
10.0.0.8 —> web #修改他

[root@web02 ~]# cat /etc/nginx/conf.d/ip.oldxu.com.conf

server {
    listen 80;
    server_name ip.oldxu.com;
    root  /php;


    set_real_ip_from 10.0.0.5;
    set_real_ip_from 10.0.0.7;                        #web前端所有的代理服务器地址,一个都不能少
    real_ip_header X-Forwarded-For;                   #那个header头检索出需要的IP地址 ( 10.0.0.1, 10.0.0.5, 10.0.0.7)
    real_ip_recursive on;                             #递归排除 set_real_ip_form里面出现的IP地址
    #剩下没有出现的IP则被认为是真实IP地址              # ( 10.0.0.1 ==$remote_addr )

    location /  {
        index index.php;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include  fastcgi_params;
    }
}

realip:直接使用就能提取到真实IP,但缺陷是他需要知道沿途经过的所有IP地址 或 地址段,但不用担心云厂商会给你清单。


4.四层负载均衡与阿里云SLB

image.png