一 DNS

DNS 是一种实现负载均衡的方式,为了扩展后端的服务能力,我们会在一个域名下配置多个 IP 地址。在 DNS 上可以配置访问策略,按照运营商、地域进行优先选择,然后按照随机的方式分配被访问的节点。

DNS 一般用在 Web 类业务中,用户在请求域名的时候,会先访问 DNS 服务器,从 DNS 服务器中解析到真正的 IP 地址,然后通过 IP 地址访问服务器。

如果服务端要做扩容或缩容,则可以通过修改 DNS 配置文件控制服务器数量、地域接入分布及权重等。

优点

配置简单,不用单独开发和维护负载均衡服务器。

缺点

存在多级缓存的问题。由于 DNS 服务器在全球呈树状结构,每一级 DNS 服务器都缓存上一级服务器的信息,客户端也会有缓存。更新不及时,就不能达到配置更新后立即刷新数据的目的。在实际开发中,甚至出现访问一个月之前老 DNS 缓存的现象。

DNS 作为一级负载均衡的手段,主要用于对不同运营商、地域进行接入和分流,后面还要配合 Nginx 或 LVS 等虚拟 IP 地址的方式作为二级缓存。

二 Nginx 

在 HTTP 服务器 Nginx 上也有实现负载均衡的功能,只需要简单地配置,就能够对后端服务进行负载均衡转发。Nginx 支持轮询、最小连接数和 ip-hash 三种方式的负载均衡。

Nginx 还可以开发插件,有很多在 Nginx 插件上建立负载均衡。

1 默认的负载均衡配置——轮询

http{
    upstream myapp1{
        server srv1.example.com weight = 3;
        server srv2.example.com;
        server srv3.example.com;
    }

    server{
        listen 80;
        location / {
            proxy_pass http://myapp1;
        }
    }
}

上面配置了三台后端 server(srv1~srv3)。该配置是轮询算法,依次把 80 端口的请求转发给后端的 srv1、srv2、srv3。如果在某个 server 上加上 weight 配置,就转换成按权重轮询,默认的权重是 1。

2 最小连接数:

upstream myapp1{
        least_conn;
        server srv1.example.com weight = 3;
        server srv2.example.com;
        server srv3.example.com;
    }

如果按照最小连接数的方案进行转发,那么只需要修改 upstream 的配置即可,在其中加上 least_conn 的配置。

3 源地址 Hash

upstream myapp1{
        ip_hash;
        server srv1.example.com weight = 3;
        server srv2.example.com;
        server srv3.example.com;
    }

Nginx 还可以按照客户端源地址进行 Hash 运算后转发,保证相同客户端的请求都能落在同一后端 server 上。只需要修改 upstream 的配置,在其中加上 ip_hash 的配置即可。

三 LVS

对于分布式网络服务,LVS(Linux Virtual server,Linux虚拟服务器)能够基于 IP 层和内容进行请求分发和负载均衡。在 Linux 内核实现调度算法,将服务器集群构成一个可伸缩高可用的网络服务的虚拟服务器。

当只用 LVS 时,对外展示的是一个虚拟 IP 地址。通过 LVS,根据负载均衡算法转到实际的实体 IP 地址上。算法可以是轮询、随机、源地址 Hash 等,提供多种方式供用户选择。而且会对后端实体机器进行健康检查,当发现后端有异常时,会删除有异常的节点,把请求转到健康节点上。后端恢复后再把请求重新接入进来。

LVS的主要实现模式如下:

  • NAT 模式——通过修改目标 IP 地址实现
  • DR 模式——通过修改目标 MAC 地址实现
  • TUN 模式——通过 IP 隧道协议实现