负载均衡

今天高考,祝愿所有高考学子能够梦想成真!取得佳绩,踏入自己理想中的学府。

再回首,18岁的青春已不复存在,恍然都长大了,不过还是要怀揣梦想一路向前!

认识负载均衡

初识

先说说自己以往对于负载均衡的认识,刚踏入职场时只停留在一种很简单的想法,就是一种保证服务正常运行的东西,它后面有一堆服务节点,反正不会因为某些节点宕机就导致服务没法用了。然后随着不断学习,对于负载均衡有了更多的认识。

再识

概念:

负载均衡(Load Balancing)就是一种网络技术,是用来将工作负载分布到多个服务器上,提高资源利用率、最大化吞吐量、最小化响应时间、避免单个服务器过载,提高了系统的性能和可靠性。

原理:

负载均衡的主要原理是什么?

1. 监听客户端请求

2. 请求发送给调度器,根据调度算法选择服务器

3. 将请求转发到选择的服务器

4. 将服务器的响应转发回客户端

用途:

负载均衡通常用于: 集群服务器之间的负载分担 增强网络服务的可靠性和可用性

常见的负载均衡算法:

1. 随机算法:简单但可能导致负载分配不均衡。

2. 轮询算法:依次将请求分发到不同服务器,简单易实现但无法考虑服务器性能。

3. 权重轮询算法:根据服务器性能设置权重,性能高的服务器分配更多请求。

4. 最少连接算法:将请求分发到连接数最少的服务器。

5. 基于响应时间的算法:根据服务器的历史响应时间进行分配,响应时间短的优先分配。

6. 故障转移算法:主服务器发生故障后,请求转发到备份服务器。

这里举例一个使用js实现简单的负载均衡的代码:

    // 服务列表
    let servers = [
    {
        name: "server1",
        url: "http://server1.example.com"
    },
    {
        name: "server2",
        url: "http://server2.example.com"
    },
    {
        name: "server3",
        url: "http://server3.example.com"
    }
    ];

    // 服务权重映射表
    let weights = {
        server1: 1,
        server2: 2,
        server3: 1
    };

    // 获取随机服务
    function getServer() {
        let total = Object.values(weights).reduce((a, b) => a + b, 0);
        let offset = Math.floor(Math.random() * total);
        let idx = 0;
    for (let key in weights) {
        if (offset < weights[key]) return servers[idx];
        offset -= weights[key];
        idx++;
    }
    } 

    // 请求处理函数
    function handleRequest(request) {
        let server = getServer();
        console.log(`Forward request to ${server.name}`);
        // 转发请求到选择的服务器
        let res = forwardRequest(request, server.url); 
        // 获取响应并返回客户端
        return res;
    }
    // 转发请求到服务URL并获取响应
    function forwardRequest(request, url) {
        let options = {
            hostname: url,
            port: 80, 
            path: request.url, 
            method: request.method
    };
    
    let res = '';
    let req = http.request(options, (response) => {
        response.on('data', (chunk) => {
        res += chunk;
        });
        response.on('end', () => {
        return res; 
        });
    });
    
    req.on('error', (err) => {
        console.log('Error: ', err);
    });
    
    req.end();
    }  

    // HTTP服务
    let server = http.createServer((req, res) => {
        let response = handleRequest(req);
        res.end(response);
    });

    // 监听客户端请求 
    listenForRequests(8888);

常见的负载均衡架构:

1. DNS 负载均衡:通过 DNS 服务器,将请求分发到不同 IP 地址的服务器。

2. 硬件负载均衡器:通过专用负载均衡硬件设备,实现负载分发和故障转移。

3. 软件负载均衡:在服务器上部署负载均衡软件(如 Nginx,LVS,HAProxy等),通过软件实现负载分配。

常见的工作模式:

- 四层负载均衡:基于 TCP/IP 协议工作,可以对任意类型的 TCP/UDP 应用进行负载均衡。如 LVS、NLB 等。

- 七层负载均衡:基于 HTTP 协议工作,主要用于 Web 应用的负载均衡。如 Nginx、HAProxy、F5 等。

- 基于代理的负载均衡:通过反向代理服务器实现负载均衡。如 Nginx、HAProxy 等。

- 硬件负载均衡器:使用专用网络设备实现负载均衡。如 F5 BIG-IP 等。

常见的负载均衡软件:

1. Nginx:轻量级的 Web 服务器和反向代理服务器,也提供基于七层的负载均衡功能。

2. HAProxy:提供高可用性、基于七层的负载均衡和基于TCP和HTTP应用的代理,主要用于整合和监控集群中各节点服务。

3. LVS: Linux Virtual Server,是 Linux 平台下的软件负载均衡解决方案,工作在四层,支持各种调度算法。

4. AWS ELB:Amazon Web Services 提供的基于七层的负载均衡服务,可在 AWS 云内对 HTTP 和 TCP 应用进行负载均衡。

5. Azure Load Balancer:Microsoft Azure 提供的负载均衡器,可在 Azure 云平台上实现基于七层的负载均衡。

常见的硬件负载均衡:

1. F5 BIG-IP:提供高级防火墙、VPN、DNS与四层和七层负载均衡功能的硬件设备。

2. A10 ADC:提供高级的软件定义网络、四层负载均衡、七层内容交付网络和DDoS防火墙等网络解决方案。

3. Citrix NetScaler:提供四层和七层负载均衡、应用交付、云网络等功能的全软件网络设备。

4. Radware Alteon:提供高级adaptative网络安全、四层负载均衡和七层应用交付等功能的硬件设备。

误区:

初识对于负载均衡和高可用两个概念有点混淆,下面就来说说其中区别。

负载均衡

主要用于增加系统的吞吐量和效率,通过在多台服务器之间分配负载,充分利用资源。

通常在传输层或应用层工作,用于分发对应层的请求。

适用于吞吐量较高的场景,提高web服务能力,如电商网站。

常用软件:Nginx、LVS、HAProxy 等。

高可用

主要用于提高系统的可靠性,通过在多台服务器之间配置冗余,避免单点故障造成的服务中断。

设计在更低的操作系统或硬件层面,避免单一设备故障。

关注系统冗余,需配置双电源、备用设备、心跳检测、故障转移等。

常用软件:Keepalived、Heartbeat、Pacemaker等。

负载均衡追求更高的性能,高可用追求更高的稳定性。实际使用的时候,两者常结合使用:既能提高性能,又能确保高可用,达到更好的效果。

浅谈LVS

LVS 是 Linux Virtual Server 的简称,是 Linux 操作系统下的一款软件负载均衡解决方案。它可以实现基于四层(TCP/IP协议)的负载均衡,对来自客户端的请求进行分发,将负载分散到多台实际的服务器上,从而提高服务能力和可靠性。

LVS采用三层结构:

第一层: 负载调度器

第二层: 服务池

第三层:共享存储

LVS 主要由两部分组成:

  1. IPVS(IP Virtual Server):Responsible for load balancing in the Linux kernel.LVS 中最核心的部分,实现请求分发与负载均衡功能。

  2. 特定的 administration 程序:用于配置 IPVS,管理真实服务器等。常用的工具有:ipvsadm、ipvsadmin 等。

LVS 的工作模式主要有三种:

  1. NAT 模式:LVS 对请求进行源地址转换后分发到后端服务器,对客户端来说只有一个 IP 地址。
  2. TUN 模式:将客户端请求数据包进行封装后转发给后端服务器,服务器直接与客户端交互。
  3. DR(Direct Routing)模式:将客户端请求数据包直接转发给后端服务器,客户端与真实服务器直接交互,LVS 只负责分发请求。

LVS 的主要配置步骤如下:

  1. 安装 LVS,启动 IPVS 内核模块。
  2. 配置虚拟服务(设置 VIP、端口、调度算法等)。常用命令:ipvsadm -A -t : -s
  3. 添加真实服务器(设置 RIP、端口、权重等)。常用命令:ipvsadm -a -t : -r : -w
  4. 启动管理程序(ipvsadm),监控服务器状态并同步配置。
  5. 配置高可用,通过 Keepalived 实现 LVS 节点故障切换。
  6. 启动 Keepalived 进行状态检测,当主节点故障时能够快速切换到备节点。

脑裂

在一个高可用集群中,由于网络故障导致集群中部分节点失去连接,但各节点本身并未故障。本来一个整体、变成独立的两个个体。争抢共享资源、这会导致集群中的数据出现不一致,影响服务的正确性和可靠性。

原因:

  1. 网络隔离:集群中部分节点之间的网络连接断开,导致节点间无法正常通信。
  2. 网络延迟:节点间网络连接出现严重延迟,导致节点间通信不稳定。
  3. 网络攻击:恶意网络攻击导致集群节点间网络通信中断。
  4. 配置不当
  5. 硬件故障
  6. 防火墙 等等

解决:

  1. 心跳检测、状态同步
  2. 监控脑裂程序
  3. 手动配置