第六节 nginx实现负载均衡

亮子 2021-08-07 21:38:13 17763 0 0 0

1、什么是负载均衡

由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其处理能力和计算强度也相应地增大,使得单一的服务器设备根本无法承担。在此情况下,如果扔掉现有设备去做大量的硬件升级,这样将造成现有资源的浪费,而且如果再面临下一次业务量的提升时,这又将导致再一次硬件升级的高额成本投入,甚至性能再卓越的设备也不能满足当前业务量增长的需求。
针对此情况而衍生出来的一种廉价有效透明的方法以扩展现有网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性的技术就是负载均衡(Load Balance)。

图片alt

  • 负载均衡的目的

提升吞吐率,提升请求性能, 提⾼高容灾。

  • 负载均衡的实现

Nginx 实现负载均衡用到了 proxy_pass 代理模块核心配置, 将客户端请求代理转发至一组 upstream 虚拟服务池。

  • 与反向代理的区别

负载均衡和反向代理的区别是,反向代理由代理服务器指定特定的服务器去请求资源,而负载均衡中的代理服务器将请求转发给虚拟服务池,具体由那个服务器处理根据相应的算法来定。

2、负载均衡的种类

  • 一种是通过硬件来进行解决,常见的硬件有NetScaler、F5、Radware和Array等商用的负载均衡器,但是它们是比较昂贵的

  • 一种是通过软件来进行解决的,常见的软件有LVS、Nginx、apache等,它们是基于Linux系统并且开源的负载均衡策略.

3、使用nginx来搭建负载均衡

  • 配置文件

    # 后端服务器
    upstream springboot-server {
        #ip_hash; # 可选。每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
        server 127.0.0.1:9000 weight=10;
        server 127.0.0.1:9001 weight=10;
        server 127.0.0.1:9002 max_fails=3 fail_timeout=30s;
        server 127.0.0.1:9003 down;     # 表示当前的 server 暂时不参与负载。
        #server 127.0.0.1:9004 backup;   # 其它所有的非 backup 机器 down 或者忙的时候,才会被请求。
    }

    # shop.abc.com
    server {
        listen       8080;
        listen       [::]:8080;
        server_name  shop.abc.com;

        location / {
            proxy_pass http://springboot-server;
            index   index.html index.htm;
        }
    }

配置详解:

  • weight=5表示权重
  • max_fails=3 表示最大失败次数
  • fail_timeout=30s 表示尝试最大失败次数之后,需要等待30秒后,接着重试
  • backup 表示备用服务器,平时用不上,一旦其他服务器挂了,就会启用备用服务器。

后端服务器在负载均衡调度中的状态

图片alt

具体配置截图:

图片alt

4、后台代码

package com.shenmazong.demorabbitsend.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author 军哥
 * @version 1.0
 * @description: 控制层接口类
 * @date 2021/8/6 11:54
 */

@RestController
@Slf4j
public class IndexController {

    @Value("${server.port}")
    private Integer port;

    @GetMapping(value = "/hello")
    public Object hello() {
        return "hello:"+port;
    }

}