• Nginx实现负载均衡


    Nginx实现负载均衡
    负载均衡的作用

    1、解决单点故障,让web服务器构成一个集群

    2、将请求平均下发给后端的web服务器

    负载均衡的软硬件介绍

    负载均衡软件:

    # nginx
    四层负载均衡:stream(nginx 1.9版本以后有stream模块,才可以做四层负载)
    七层负载均衡:upstream模块
    
    # HAproxy
    四层负载均衡
    四层负载均衡
    
    # LVS
    只能做四层负载:不识别域名,只识别端口。也就是只能做端口转发、端口代理。但同样四层,LVS的速度是最快的。why?
    
    LVS,它是直接把你物理服务器变成硬件的负载均衡。
    
    用命令 ipvsadm
    
    修改网络和路由配置,直接这台机器变负载均衡。请求到达服务器就直接向后转发了,无需经过像nginx这些应用
       
    ###软件如何选?
    中小型:nginx
    大型互联网公司:前端LVS做四层转发,后端nginx做七层转发
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    负载均衡硬件:

    F5、Netscaler等。淘宝、赶集网、新浪等公司使用过 Netscaler 负载均衡产品。

    ###硬件如何选型?

    当企业业务重要、技术力量又薄弱,并且希望出钱购买产品及获取更好的服务时,可以选择硬件负载均衡产品,如 F5、Netscaler等,此类公司多为传统的大型非互联网企业,如银行、证券、金融、宝马、奔驰等。

    对于门户网站来说,大多会并用软件及硬件产品来分担单一产品的风险,如淘宝、腾讯、新浪等。融资企业可能会购买硬件产品,如赶集等网站。

    中小型互联网企业由于起步阶段无利润或者利润很低,会希望通过使用开源免费的方案来解决问题,因此会雇用专门的运维人员进行维护。

    相比较而言,商业的负载均衡产品成本高、性能好,更稳定,缺点是不能二次开发,开源的负载均衡软件对运维人员的能力要求较高,如果运维及开发能力强,那么开源软件的负载均衡是不错的选择,目前的互联网行业更偏向使用开源的负载均衡软件
    云服务的负载均衡:

    阿里云:SLB

    亚马逊上被称作ELB

    各种叫法不同,作用都是一样的

    七层和四层的区别
    四层负载均衡数据包在底层就进行了分发,而七层负载均衡数据包则是在最顶层进行分发。由此可以看出,七层负载均衡效率没有四负载均衡高。

    但七层负载均衡更贴近于服务,如http协议就是七层协议,我们可以用Nginx可以作会话保持,URL路径规则匹配、head头改写等等,这些是四层负载均衡无法实现的。

    四层,走四层 传输层

    七层,走七层 应用层

    区别:四层较快,但无法识别域名,七层可以识别域名

    nginx实现简单负载均衡

    简单架构图:
    在这里插入图片描述
    环境准备

    在这里插入图片描述

    简单web站点准备
    
    # web01 web02
    gzip -r /etc/nginx/conf.d/* (可以把conf.d目录下之前的配置都打包备份)
    cd /etc/nginx/conf.d
    vim lb.xxx.conf
    
    server{
          listen 9999;  #开放9999端口
          server_name lb.xxx.com;
          root /code/lb;
          index index.html;
    }
    
    
    # 创建站点目录
    mkdir -p /code/lb
    
    # 创建index.html
    echo 'web01' > /code/lb/index.html   //web01的配置
    echo 'web02' > /code/lb/index.html   //web02的配置
    
    # 检测语法并重启
    nginx -t
    systemctl reload nginx
    
    # 检查端口
    [root@web01 /code/lb]# netstat -lntup
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      10916/php-fpm: mast
    tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN      15540/nginx: master
    ...
    
    # 本地域名解析
    #10.0.0.5 lb.xxx.com
    10.0.0.7 lb.xxx.com
    #10.0.0.8 lb.xxx.com
    
    # 分别访问web01和web02
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    在这里插入图片描述
    在这里插入图片描述

    负载均衡配置(lb01)
    
    # lb01
    [root@lb01 ~]# cd /etc/nginx/conf.d
    [root@lb01 /etc/nginx/conf.d]# vim lb.conf
    upstream www_pools{      #//自定义服务器池名www_pools,这里包括web01和web02两个web节点
          server 172.16.1.7:9999;
          server 172.16.1.8:9999;
    }
    server {       #//定义代理的负载均衡域名虚拟主机  
          listen 80;
          server_name lb.xxx.com;
          location / {
                  proxy_pass http://www_pools;    #//访问lb.xxx.com,请求发给www_pools里面的节点
                  include /etc/nginx/conf.d/proxy_params;   #//反向代理参数
          }
    }
    
    [root@lb01 /etc/nginx/conf.d]# cat proxy_params
    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_connect_timeout 30;
    proxy_send_timeout 60;
    proxy_read_timeout 60;
    
    proxy_buffering on;
    proxy_buffer_size 32k;
    proxy_buffers 4 128k;
    
    # 检查语法,重载nginx
    nginx -t
    nginx -s reload
    
    # 本地域名解析
    10.0.0.5 lb.xxx.com
    #10.0.0.7 lb.xxx.com  
    #10.0.0.8 lb.xxx.com  
    
    
    # 访问。此时刷新浏览器,一次访问web01,下一次访问web02
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述

    负载均衡核心组件Upstream模块
    
    Nginx实现负载均衡的组件主要有两个。一个是proxy模块,还有一个是upstream模块ngx_http_upstream_module,这是nginx实现负载均衡的核心组件。它支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等,新版Nginx支持的方式有所增加。我们主要针对proxy_pass代理方式讲解。
    
    ngx_http_upstream_module模块允许Nginx定义一组或多组web节点(服务器节点),使用时可以通过proxy_pass把网站的请求发送到事先定义好的upstream组上。具体写法为:proxy_pass http://abc 。其中abc就是一个upstream组名。 
    
    注意upstream 仅仅是定义服务器池,并不会直接处理用户的请求,必须要有其他方式将请求转给这个服务器池(比如proxy_pass)才行。
    
    upstream模块的内容应放于http{}层,即与server层平齐。其默认调度算法为wrr(weight默认为1,即rr)
    
    官方网站:
    
    https://nginx.org/en/docs/http/ngx_http_upstream_module.html
    
    
    
    Upstream模块语法
    
    
    
    # 基本配置示例
    upstream www_pools{      #//upstream为关键字,必须要有,www_pools为自定义组名
          server 172.16.1.7:9999  weight=5;    
          server 172.16.1.8:9999  weight=10;
          server 172.16.1.9:9999  weight=15; #//server为固定关键字,后面可以接域名或IP。如不指定端口,默认80
    }
    
    # 较完整的upstream配置示例
    upstream backend {                                  
    server 10.0.0.7;   #//此标签等价于下面标签,多出来的是默认值,可以不写
    server 10.0.0.8:80 weight=1 max_fails=2 fail_timeout=10s;
    }
    
    参数解释:
    weight         #weight代表服务器权重,数值越大被分配的请求越多。默认值为1
    max_fails      #Nginx尝试连接后端主机失败的次数,默认1,京东1,建议2-3次
    fail_timeout   #在max_fails定义的失败次数后,距离下次检查的时间间隔,默认10s,常规业务建议2-3s(比如京东是3s)
    down           该服务器不可用。配合ip_hash使用
    
    比如 max_fails=2 fail_timeout=10s 意思是2次连续检测失败后,间隔10s在重新检测。
    
    # 使用域名及socket的示例
    upstream backend {                                      
      server backend1.example.com weight=5;
      server backend2.example.com:8080;           #//域名+端口。
      server unix:/tmp/backend3;                  #//指定socket文件
      server backup1.example.com:8080   backup;   #//backup表示备份服务器(备节点),其他服务器都不可访问时启用。
      server backup2.example.com:8080   backup;
    }
    
    ps: server后面如果接域名,需要内网有DNS服务器或者在负载均衡的hosts文件做域名解析。
    
    Upstream模块调度算法
    
    调度算法一般分为以下两类:—类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器情況。例如rr、wrr、ip_ hash都属于静态调度算法。第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求。例如:连接数少的优先获得请求,响应时间短的优先获得请求。least_conn 、fair等属于动态调度算法。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    Upstream模块调度算法

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

    1、rr轮询(Round Robin,默认调度算法,静态调度算法)
    	每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除;
    2、wrr轮询(weight Round Robin,权重轮询,静态调度算法)
    	在轮询算法的基础上加上权重weight,权重轮询和访问成正比,权重值越大,转发的请求也就越多;
    3、ip_hash(静态调度算法)
    	每个请求按访问的IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法希出一个值,在随后请求中客户端ip的哈希值只要相同,就会被分值至同一台服务器,该调度算法可以解决网页session共享问题,但有时会导致请求分配不均和无法保证相对的负载均衡;
    	注意:当调度算法是ip_hash 时,后端服务器中负载均衡调度中的状态不能有weight和backup,即使有也不会生效。
    4、fair(动态调度算法)
    	按照后端服务器节点的响应时间来智能分配请求,响应时间短的优先分配,这中调度算法是更加智能的算法,这种算法可以依据页面大小和加载时间长短智能的进行负载均衡,nginx本身不支持fair,需要下载nginx的upstream_fair模块;
    5、least_conn(动态调度算法)
    	根据后端节点的连接数来决定分配情况,哪个后端节点连接数少就连接哪个;
    6、url_hash
    	与ip_hash调度算法类似,但url_hash是按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,这当后端服务器是缓存服务器时效果更显著;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    加权轮询的例子

    [root@lb01 /etc/nginx/conf.d]# cat lb.xxx.conf
    upstream lb.xxx.com{
    server 172.16.1.7:9999 weight=3;  #//实测这样配置是先一次web01,再两次web02(1:2)
    server 172.16.1.8:9999 weight=6;
    }
    server {
    listen 80;
    server_name lb.xxx.com;
    
    location / {
    proxy_pass http://lb.xxx.com;
    include /etc/nginx/conf.d/proxy_params;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ip_hash的例子

    upstream lb.xxx.com{
          ip_hash;    #//加一下即可。这时它就一直访问web01。如果.8在上面就一直访问web02
          server 172.16.1.7:9999;
          server 172.16.1.8:9999;
          server 172.16.1.9:9999;
    }
    server {
          listen 80;
          server_name lb.xxx.com;
    
    location / {
          proxy_pass http://lb.xxx.com;
          include /etc/nginx/conf.d/proxy_params;
          }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意用ip_hash时不要再写入weight和backup两个参数,即使写了也不会生效

  • 相关阅读:
    Unity --- 摄像机的选择与设置
    .env[mode]文件中如何添加注释
    【HCIP】BGP 基础
    Educational Codeforces Round 157 (A--D)视频详解
    数据库基础(一)
    Taurus.MVC WebMVC 入门开发教程4:数据列表绑定List<Model>
    Spring Boot拦截器Interceptor
    EN 1504-6混凝土结构保护和修理用产品钢筋锚固—CE认证
    设计模式之——简单工厂模式
    关于【统一权限系统】概况
  • 原文地址:https://blog.csdn.net/weixin_45817985/article/details/134440738