标签 负载均衡 下的文章

2011 年 3 月,苹果公司提出 RFC 6186,描述了如何利用域名系统服务(DNS SRV)记录来查找电子邮件的提交以及访问服务。现在 Postfix 从 3.8.0 版本开始支持 RFC 中提出的设计。这个新增功能让你可以使用 DNS SRV 记录进行负载分配和自动配置。

DNS SRV 记录的形态

DNS SRV 记录定义在 RFC 2782 中,它指定在区域文件中,并且包含了服务名称、传输协议规范、优先级、权重、端口,以及提供该服务的主机。

_submission._tcp    SRV 5 10 50 bruce.my-domain.com.
字段意义
服务名称submission服务名为 submission
传输协议规范tcp本服务使用 TCP 协议
优先级5服务器优先级设为 5(数值越小,优先级越高)
权重10服务器应承担的负载部分
端口50服务器监听连接的端口
目标bruce.my-domain.com.提供此服务的服务器名称

记录解释

服务器选择算法

客户端应该按照 RFC 2782 中描述的方式解析 SRV 记录。这意味着,首先尝试联系拥有最高优先级(最小的优先级数字)的服务器。如果该服务器无回应,那么重试联系拥有同样或者更低优先级的下一台服务器。当有多台服务器拥有同样优先级的时候,应随机选择其中一台,但是必须确保选择记录的概率符合下列公式:

其中 i 是 SRV 记录的标识,k 是具有相同优先级的 SRV 记录的数量。

在现实中,这意味着如果你有两台服务器,其中一台的处理能力是另一台的三倍,那么你应该给第一台服务器的权重赋于另一台三倍的值。这样就能保证更强大的服务器会接收到大约 75% 的客户端请求,而另一台接收大约 25% 的请求。

这些原则使得 SRV 记录能够同时作为客户端自动配置及在服务器之间分配工作负载的工具。

看看以下这个记录的例子:

_submission._tcp     SRV 0 0 2525 server-one
_submission._tcp     SRV 1 75 2625 server-two
_submission._tcp     SRV 1 25 2625 server-three

这里 server-one 总是会被首选来进行联系。如果 server-one 无回应,客户端就会将剩下优先级为 1 的两个记录顺序打乱,生成一个从 0 到 100 的随机数,如果第一条记录的运行总和大于或者等于这个随机数,它就会尝试去联系这个记录。否则,客户端会倒序联系所有服务器。注意,客户端会向它优先成功连接的服务器发送请求。

示例配置

请考虑以下这种情况。你想为大量的电脑配置 Postfix,使其通过公司的邮件服务器利用 SRV 记录转发外部电邮。为了达到这个目标,你需要在每台电脑的 Postfix 中配置 relayhost 参数,即邮件用户代理(MUA)。如果将 relayhost 参数的值设置为 $mydomain,你的机器将开始为你的域名查找 MX 记录,并尝试按照它们的优先级顺序发送邮件。这种方法虽然有效,但是可能会遇到负载平衡问题。Postfix 会使用优先级最高的服务器,直到其变为无响应才会联系其他备用服务器。此外,如果你在环境中使用了动态分配的端口,你无法指明哪个端口正在被特定的服务器使用。使用 SRV 记录,你可以应对这些挑战,并在需要改变服务器端口的时候维持服务器的平滑运行。

区域文件

为了使得 DNS 服务器提供信息给客户端,可以参考以下使用服务器 server-oneserver-twoserver-three 作为中继,并把服务器 server-four 配置为接收测试邮件的区域文件示例。

$TTL  3600
@       IN SOA  example-domain.com. root.example-domain.com. (
                1571655122 ; 区域文件的序列号
                1200       ; 刷新时间
                180        ; 发生问题时的重试时间
                1209600    ; 过期时间
                10800 )    ; 查询失败时的最大缓存时间
;
        IN NS   ns1
        IN A    192.168.2.0
;
ns1     IN A    192.168.2.2
server-one           IN A   192.168.2.4
server-two           IN A   192.168.2.5
server-three         IN A   192.168.2.6
server-four          IN A   192.168.2.7
_submission._tcp     SRV 0 0 2525  server-one
_submission._tcp     SRV 1 50 2625 server-two
_submission._tcp     SRV 1 50 2625 server-three
@ MX 0 server-four

Postfix MUA 配置

设置客户端机器去查找 SRV 记录:

use_srv_lookup = submission
relayhost = example-domain.com:submission

通过这个配置,你的客户端机器上的 Postfix 实例会联络到 example-domain 的 DNS 服务器,然后获取邮件提交的 SRV 记录。在这个例子中,server-one 有最高的优先级,Postfix 会先试图连接它。然后,Postfix 随机的选择剩下的两个服务器其中一个去尝试连接。这个配置确保了大约有 50% 的机会会优先联系到服务器一。注意,SRV 记录的权重值并不等同于百分比。你也可以用 1 和 1 这样的值达到同样的目标。

同时,Postfix 也知道 server-one 在监听 2525 端口,而 server-two 在监听 2625 端口。如果你正在缓存检索到的 DNS 记录,并且你动态改变 SRV 记录,那么设置一个低的生存时间(TTL)对你的记录是很重要的。

整套设置

你可以通过下面的方式尝试这个配置,包含 podman 和在此处提供的 compose 文件:

$ git clone https://github.com/TomasKorbar/srv_article
$ cd srv_article/environment
$ podman-compose up
$ podman exec -it article_client /bin/bash
root@client # ./senddummy.sh
root@client # exit

完成配置之后,你可以检查日志,查看邮件是否经过 server-one 并最终投递到 server-four

$ podman stop article_server1
$ podman exec -it article_client /bin/bash
root@client # ./senddummy.sh
root@client # ./senddummy.sh
root@client # ./senddummy.sh
root@client # ./senddummy.sh
root@client # ./senddummy.sh
root@client # ./senddummy.sh
root@client # exit

现在 server-one 已经关闭了,这六封邮件将会由 server-two 或者 server-three 中转发出去。

仔细看一下 Dockerfiles 以更深地理解这个配置。

通过执行:$ podman-compose down 完成示例的操作。

(题图:DA/241079fe-58d6-4dc6-8801-f0fd19dfd64b)


via: https://fedoramagazine.org/using-postfix-dns-srv-record-resolution-feature/

作者:Tomáš Korbař 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

负载均衡就是将资源分配到某一时刻最需要它的地方。

 title=

当个人电脑刚开始发展的时候,一个家庭可能只有一台(或更少)的电脑。孩子们白天玩电脑游戏,家长们晚上在业务支撑系统上做会计、编程,或者漫游。然而,想象一下今天一个只有一台电脑的家庭,你可以预想到这样会产生什么样的冲突。每个人都想使用电脑,而只有一副键盘和鼠标。

随着计算机变得越来越普遍,IT 行业或多或少也出现了同样的情况。对服务和服务器的需求已经增长到了会因为用量过大而停机的程度。幸运的是,我们现在有了负载均衡的概念来帮助我们处理需求。

负载均衡是什么?

负载均衡是一个通用术语,指的是为了确保高效分配所管理的资源而做的事情。对于 Web 服务器的系统管理员来说,负载均衡通常意味着确保 Web 服务器软件(例如 Nginx)配置了足够的工作节点来处理激增的访客。换言之,如果一个网站突然变得非常受欢迎,其访问者在几分钟内增加了四倍,那么运行服务器的软件必须能够响应每个访问者,并不能让任何访问者发现服务质量下降。对于简单的网站,这就像修改一行配置选项一样简单,但对于具有动态内容的复杂站点,每个用户都有多个数据库查询,这可能是一个严重的问题。

这个问题本应随着云计算的发展而解决,但当 Web 应用程序遇到意外激增时,无法扩展也不是不可能。

在进行负载均衡时,需要记住的重要一点是,高效地分配资源并不一定意味着平均地分配资源。并非所有任务都在任何时候都需要所有的可用资源。一个智能的负载均衡策略仅在需要资源时才为用户和任务提供资源。这通常是应用程序开发人员的领域,而不是 IT 基础架构的责任。异步应用程序对于确保离开计算机休息的用户不占用服务器上的宝贵资源至关重要。

负载均衡是怎么工作的?

负载均衡通过在多个计算节点上分配工作负载来避免瓶颈。这些节点可能是数据中心中的物理服务器、云环境中的容器、用于边缘计算而战略性放置的服务器、复杂应用程序框架中的独立 Java 虚拟机(JVM),或在单个 Linux 服务器上运行的守护进程。

这个想法是把一个大问题分成几个小任务,并把每个任务分配给一台专用计算机。例如,对于一个要求用户登录的网站,该网站可能托管在服务器 A 上,而登录页面和所有随附的身份验证查询都托管在服务器 B 上。这样,新用户登录帐户时就不会占用其它使用该站点的用户的资源。

云计算负载均衡

云计算使用 容器,因此通常没有单独的物理服务器来处理不同的任务(实际上,有许多单独的服务器,但它们被聚集在一起作为一个计算“大脑”)。相反,“ 容器荚 pod ” 是由几个容器创建的。当一个容器荚由于其用户或任务负载而开始耗尽资源时,会生成一个相同的容器荚。容器荚共享存储和网络资源,每个容器荚在创建时被分配给一个计算节点。可以根据负载需要创建或销毁容器荚,这样无论有多少用户,用户都可以体验到一致的服务质量。

边缘计算

边缘计算 在负载均衡时考虑到了现实世界。云计算自然是一个分布式系统,但实际上,云计算的节点通常集中在几个数据中心。用户离运行云计算的数据中心越远,他们为获得最佳服务所必须克服的物理障碍就越多。即使有光纤连接和适当的负载均衡,位于 3000 英里外的服务器的响应时间也可能比仅仅 300 英里外的响应时间长。

边缘计算将计算节点带到云计算的“边缘”,试图弥合地理鸿沟,为云计算形成一种卫星网络,因此它也在良好的负载均衡工作中发挥了作用。

什么是负载均衡算法?

有许多负载均衡策略,它们的复杂性取决于所涉及的技术和需求。负载均衡不必复杂,而且从一开始就负载均衡很重要,即使在使用 KubernetesKeepalived 这样的专用软件时也是如此。

当你可以设计应用程序,自己为它采取简单的预防措施时,不要依赖容器来均衡负载。如果你从一开始就将应用程序设计为模块化和临时性的,那么你将受益于通过巧妙的网络设计、容器编排和其他未来技术带来的负载均衡机会。

可以指导应用程序开发人员或网络工程师工作的一些流行算法包括:

  • 按顺序将任务分配给服务器(这通常被称为轮询调度)。
  • 将任务分配给当前最不繁忙的服务器。
  • 将任务分配给具有响应最快的服务器。
  • 随机分配任务。

举个例子,在分配特别复杂的任务时,可以组合或加权这些原则以分配到组中最强大的服务器。通常使用 编排,这样管理员就不必为负载均衡寻找完美的算法或策略,尽管有时需要由管理员选择使用哪种负载均衡方案组合。

预料意料之外

负载均衡实际上并不是要确保在整个网络中均匀使用所有资源。负载均衡实际上是确保即使发生意外情况也能提供可靠的用户体验。良好的基础设施可以承受计算机崩溃、应用程序过载、网络流量冲击和用户错误。思考你的服务如何才能具有弹性,并从头开始相应地设计负载均衡策略。


via: https://opensource.com/article/21/4/load-balancing

作者:Seth Kenlon 选题:lujun9972 译者:FYJNEVERFOLLOWS 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

安装、配置和运行 HAProxy,在几个网络或应用服务器之间分配网络流量。

 title=

不是只有在一个大型公司工作才需要使用负载平衡器。你可能是一个业余爱好者,用几台树莓派电脑自我托管一个网站。也许你是一个小企业的服务器管理员;也许你确实在一家大公司工作。无论你的情况如何,你都可以使用 HAProxy 负载平衡器来管理你的流量。

HAProxy 被称为“世界上最快和使用最广泛的软件负载平衡器”。它包含了许多可以使你的应用程序更加安全可靠的功能,包括内置的速率限制、异常检测、连接排队、健康检查以及详细的日志和指标。学习本教程中所涉及的基本技能和概念,将有助于你使用 HAProxy 建立一个更强大的、远为强大的基础设施。

为什么需要一个负载平衡器?

负载平衡器是一种在几个网络或应用服务器之间轻松分配连接的方法。事实上,HAProxy 可以平衡任何类型的传输控制协议(TCP)流量,包括 RDP、FTP、WebSockets 或数据库连接。分散负载的能力意味着你不需要因为你的网站流量比谷歌大就购买一个拥有几十万 G 内存的大型网络服务器。

负载平衡器还为你提供了灵活性。也许你现有的网络服务器不够强大,无法满足一年中繁忙时期的峰值需求,你想增加一个,但只是暂时的。也许你想增加一些冗余,以防一个服务器出现故障。有了 HAProxy,你可以在需要时向后端池添加更多的服务器,在不需要时删除它们。

你还可以根据情况将请求路由到不同的服务器。例如,你可能想用几个缓存服务器(如 Varnish)来处理你的静态内容,但把任何需要动态内容的东西,如 API 端点,路由到一个更强大的机器。

在这篇文章中,我将通过设置一个非常基本的 HAProxy 环境,使用 HTTPS 来监听安全端口 443,并利用几个后端 Web 服务器。它甚至会将所有进入预定义 URL(如 /api/)的流量发送到不同的服务器或服务器池。

安装 HAProxy

要开始安装,请启动一个新的 CentOS 8 服务器或实例,并使系统达到最新状态:

$ sudo yum update -y

这通常会持续一段时间。在等待的时候给自己拿杯咖啡。

这个安装有两部分:第一部分是安装 yum 版本的 HAProxy,第二部分是编译和安装你的二进制文件,用最新的版本覆盖以前的 HAProxy。用 yum 安装,在生成 systemd 启动脚本等方面做了很多繁重的工作,所以运行 yum install,然后从源代码编译,用最新的版本覆盖 HAProxy 二进制:

$ sudo yum install -y haproxy

启用 HAProxy 服务:

$ sudo systemctl enable haproxy

要升级到最新版本(版本 2.2,截至本文写作为止),请编译源代码。许多人认为从源代码编译和安装一个程序需要很高的技术能力,但这是一个相当简单的过程。首先,使用 yum 安装一些提供编译代码工具的软件包:

$ sudo yum install dnf-plugins-core
$ sudo yum config-manager --set-enabled PowerTools
$ sudo yum install -y git ca-certificates gcc glibc-devel \
    lua-devel pcre-devel openssl-devel systemd-devel \
    make curl zlib-devel 

使用 git 获得最新的源代码,并改变到 haproxy 目录:

$ git clone http://git.haproxy.org/git/ haproxy
$ cd haproxy

运行以下三个命令来构建和安装具有集成了 Prometheus 支持的 HAProxy:

$ make TARGET=linux-glibc USE_LUA=1 USE_OPENSSL=1 USE_PCRE=1 \
    PCREDIR= USE_ZLIB=1 USE_SYSTEMD=1 \
    EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o"

$ sudo make PREFIX=/usr install # 安装到 /usr/sbin/haproxy

通过查询版本来测试它:

$ haproxy -v

你应该看到以下输出:

HA-Proxy version 2.2.4-b16390-23 2020/10/09 - https://haproxy.org/

创建后端服务器

HAProxy 并不直接提供任何流量,这是后端服务器的工作,它们通常是网络或应用服务器。在这个练习中,我使用一个叫做 Ncat 的工具,它是网络领域的“瑞士军刀”,用来创建一些极其简单的服务器。安装它:

$ sudo yum install nc -y

如果你的系统启用了 SELinux,你需要启用端口 8404,这是用于访问 HAProxy 统计页面的端口(下面有解释),以及你的后端服务器的端口:

$ sudo dnf install policycoreutils-python-utils
$ sudo semanage port -a -t http_port_t  -p tcp 8404
$ sudo semanage port -a -t http_port_t  -p tcp 10080
$ sudo semanage port -a -t http_port_t  -p tcp 10081
$ sudo semanage port -a -t http_port_t  -p tcp 10082

创建两个 Ncat 网络服务器和一个 API 服务器:

$ while true ;
do
nc -l -p 10080 -c 'echo -e "HTTP/1.1 200 OK\n\n This is Server ONE"' ;
done &

$ while true ;
do
nc -l -p 10081 -c 'echo -e "HTTP/1.1 200 OK\n\n This is Server TWO"' ;
done &

$ while true ;
do
nc -l -p 10082 -c 'echo -e "HTTP/1.1 200 OK\nContent-Type: application/json\n\n { \"Message\" :\"Hello, World!\" }"' ;
done &

这些简单的服务器打印出一条信息(如“This is Server ONE”),并运行到服务器停止为止。在现实环境中,你会使用实际的网络和应用程序服务器。

修改 HAProxy 的配置文件

HAProxy 的配置文件是 /etc/haproxy/haproxy.cfg。你在这里进行修改以定义你的负载平衡器。这个 基本配置 将让你从一个工作的服务器开始:

global
    log         127.0.0.1 local2
    user        haproxy
    group       haproxy

defaults 
    mode                    http
    log                     global
    option                  httplog

frontend main
    bind *:80
        
    default_backend web
    use_backend api if { path_beg -i /api/ }
    
    #-------------------------
    # SSL termination - HAProxy handles the encryption.
    #    To use it, put your PEM file in /etc/haproxy/certs  
    #    then edit and uncomment the bind line (75)
    #-------------------------
    # bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem ssl-min-ver TLSv1.2
    # redirect scheme https if !{ ssl_fc }

#-----------------------------
# Enable stats at http://test.local:8404/stats
#-----------------------------

frontend stats
    bind *:8404
    stats enable
    stats uri /stats
#-----------------------------
# round robin balancing between the various backends
#-----------------------------

backend web
    server web1 127.0.0.1:10080 check
    server web2 127.0.0.1:10081 check

#-----------------------------

# API backend for serving up API content
#-----------------------------
backend api
    server api1 127.0.0.1:10082 check

重启并重新加载 HAProxy

HAProxy 可能还没有运行,所以发出命令 sudo systemctl restart haproxy 来启动(或重新启动)它。“重启” 的方法在非生产情况下是很好的,但是一旦你开始运行,你要养成使用 sudo systemctl reload haproxy 的习惯,以避免服务中断,即使你的配置中出现了错误。

例如,当你对 /etc/haproxy/haproxy.cfg 进行修改后,你需要用 sudo systemctl reload haproxy 来重新加载守护进程,使修改生效。如果有错误,它会让你知道,但继续用以前的配置运行。用 sudo systemctl status haproxy 检查 HAProxy 的状态。

如果它没有报告任何错误,你就有一个正在运行的服务器。在服务器上用 curl 测试,在命令行输入 curl http://localhost/。如果你看到 “This is Server ONE”,那就说明一切都成功了!运行 curl 几次,看着它在你的后端池中循环,然后看看当你输入 curl http://localhost/api/ 时会发生什么。在 URL 的末尾添加 /api/ 将把所有的流量发送到你池子里的第三个服务器。至此,你就有了一个正常运作的负载平衡器

检查你的统计资料

你可能已经注意到,配置中定义了一个叫做 stats 的前端,它的监听端口是 8404:

frontend stats
    bind *:8404
    stats uri /stats
    stats enable

在你的浏览器中,加载 http://localhost:8404/stats。阅读 HAProxy 的博客 学习 HAProxy 的统计页面,了解你在这里可以做什么。

一个强大的负载平衡器

虽然我只介绍了 HAProxy 的几个功能,但你现在有了一个服务器,它可以监听 80 和 443 端口,将 HTTP 流量重定向到 HTTPS,在几个后端服务器之间平衡流量,甚至将匹配特定 URL 模式的流量发送到不同的后端服务器。你还解锁了非常强大的 HAProxy 统计页面,让你对你的系统有一个很好的概览。

这个练习可能看起来很简单,不要搞错了,你刚刚建立和配置了一个非常强大的负载均衡器,能够处理大量的流量。

为了你方便,我把本文中的所有命令放在了 GitHub Gist 中。


via: https://opensource.com/article/20/11/load-balancing-haproxy

作者:Jim O'Connell 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

均衡网络流量的常用技术,它们的优势和利弊权衡。

大型的多站点互联网系统,包括内容分发网络(CDN)和云服务提供商,用一些方法来均衡来访的流量。这篇文章我们讲一下常见的流量均衡设计,包括它们的技术手段和利弊权衡。

早期的云计算服务提供商,可以提供单一一台客户 Web 服务器,分配一个 IP 地址,然后用一个便于人读的域名配置一个 DNS 记录指向这个 IP 地址,再将 IP 地址通过边界网关协议(BGP)宣告出去,BGP 是在不同网络之间交换路由信息的标准方式。

这本身并不是负载均衡,但是能在冗余的多条网络路径中进行流量分发,而且可以利用网络技术让流量绕过不可用的网络,从而提高了可用性(也引起了非对称路由的现象)。

简单的 DNS 负载均衡

随着来自客户的流量变大,老板希望服务是高可用的。你上线第二台 web 服务器,它有自己独立的公网 IP 地址,然后你更新了 DNS 记录,把用户流量引到两台服务器上(内心希望它们均衡地提供服务)。在其中一台服务器出故障之前,这样做一直是没有问题的。假设你能很快地监测到故障,可以更新一下 DNS 配置(手动更新或者通过软件)删除解析到故障机器的记录。

不幸的是,因为 DNS 记录会被缓存,在客户端缓存和它们依赖的 DNS 服务器上的缓存失效之前,大约一半的请求会失败。DNS 记录都有一个几分钟或更长的生命周期(TTL),所以这种方式会对系统可用性造成严重的影响。

更糟糕的是,部分客户端会完全忽略 TTL,所以有一些请求会持续被引导到你的故障机器上。设置很短的 TTL 也不是个好办法,因为这意味着更高的 DNS 服务负载,还有更长的访问时延,因为客户端要做更多的 DNS 查询。如果 DNS 服务由于某种原因不可用了,那设置更短的 TTL 会让服务的访问量更快地下降,因为没那么多客户端有你网站 IP 地址的缓存了。

增加网络负载均衡

要解决上述问题,可以增加一对相互冗余的四层(L4)网络负载均衡器,配置一样的虚拟 IP 地址(VIP)。均衡器可以是硬件的,也可以是像 HAProxy 这样的软件。域名的 DNS 记录指向 VIP,不再承担负载均衡的功能。

 title=

四层负载均衡器能够均衡用户和两台 web 服务器的连接

四层均衡器将网络流量均衡地引导至后端服务器。通常这是基于对 IP 数据包的五元组做散列(数学函数)来完成的,五元组包括:源地址、源端口、目的地址、目的端口、协议(比如 TCP 或 UDP)。这种方法是快速和高效的(还维持了 TCP 的基本属性),而且不需要均衡器维持每个连接的状态。(更多信息请阅读谷歌发表的 Maglev 论文,这篇论文详细讨论了四层软件负载均衡器的实现细节。)

四层均衡器可以对后端服务做健康检查,只把流量分发到健康的机器上。和使用 DNS 做负载均衡不同的是,在某个后端 web 服务故障的时候,它可以很快地把流量重新分发到其他机器上,虽然故障机器的已有连接会被重置。

当后端服务器的能力不同时,四层均衡器可以根据权重做流量分发。它为运维人员提供了强大的能力和灵活性,而且硬件成本相对较小。

扩展到多站点

系统规模在持续增长。你的客户希望能一直使用服务,即使是数据中心发生故障的时候。所以你建设了一个新的数据中心,另外独立部署了一套服务和四层负载均衡器集群,仍然使用同样的 VIP。DNS 的设置不变。

两个站点的边缘路由器都把自己的地址空间宣告出去,包括 VIP 地址。发往该 VIP 的请求可能到达任何一个站点,取决于用户和系统之间的网络是如何连接的,以及各个网络的路由策略是如何配置的。这就是泛播。大部分时候这种机制可以很好的工作。如果一个站点出问题了,你可以停止通过 BGP 宣告 VIP 地址,客户的请求就会迅速地转移到另外一个站点去。

 title=

多个站点使用泛播提供服务

这种设置有一些问题。最大的问题是,不能控制请求流向哪个站点,或者限制某个站点的流量。也没有一个明确的方式把用户的请求转到距离他最近的站点(为了降低网络延迟),不过,网络协议和路由选路配置在大部分情况下应该能把用户请求路由到最近的站点。

控制多站点系统中的入站请求

为了维持稳定性,需要能够控制每个站点的流量大小。要实现这种控制,可以给每个站点分配不同的 VIP 地址,然后用简单的或者有权重的 DNS 轮询来做负载均衡。

 title=

多站点提供服务,每个站点使用一个主 VIP,另外一个站点作为备份。基于能感知地理位置的 DNS。

现在有两个问题。

第一、使用 DNS 均衡意味着会有被缓存的记录,如果你要快速重定向流量的话就麻烦了。

第二、用户每次做新的 DNS 查询,都可能连上任意一个站点,可能不是距离最近的。如果你的服务运行在分布广泛的很多站点上,用户会感受到响应时间有明显的变化,取决于用户和提供服务的站点之间有多大的网络延迟。

让每个站点都配置上其他所有站点的 VIP 地址,并宣告出去(因此也会包含故障的站点),这样可以解决第一个问题。有一些网络上的小技巧,比如备份站点宣告路由时,不像主站点使用那么具体的目的地址,这样可以保证每个 VIP 的主站点只要可用就会优先提供服务。这是通过 BGP 来实现的,所以我们应该可以看到,流量在 BGP 更新后的一两分钟内就开始转移了。

即使离用户最近的站点是健康而且有服务能力的,但是用户真正访问到的却不一定是这个站点,这个问题还没有很好的解决方案。很多大型的互联网服务利用 DNS 给不同地域的用户返回不同的解析结果,也能有一定的效果。不过,因为网络地址的结构和地理位置无关,一个地址段也可能会改变所在位置(例如,当一个公司重新规划网络时),而且很多用户可能使用了同一个 DNS 缓存服务器。所以这种方案有一定的复杂度,而且容易出错。

增加七层负载均衡

又过了一段时间,你的客户开始要更多的高级功能。

虽然四层负载均衡可以高效地在多个 web 服务器之间分发流量,但是它们只针对源地址、目标地址、协议和端口来操作,请求的内容是什么就不得而知了,所以很多高级功能在四层负载均衡上实现不了。而七层(L7)负载均衡知道请求的内容和结构,所以能做更多的事情。

七层负载均衡可以实现缓存、限速、错误注入,做负载均衡时可以感知到请求的代价(有些请求需要服务器花更多的时间去处理)。

七层负载均衡还可以基于请求的属性(比如 HTTP cookies)来分发流量,可以终结 SSL 连接,还可以帮助防御应用层的拒绝服务(DoS)攻击。规模大的 L7 负载均衡的缺点是成本 —— 处理请求需要更多的计算,而且每个活跃的请求都占用一些系统资源。在一个或者多个 L7 均衡器前面运行 L4 均衡器集群,对扩展规模有帮助。

结论

负载均衡是一个复杂的难题。除了上面说过的策略,还有不同的负载均衡算法,用来实现负载均衡器的高可用技术、客户端负载均衡技术,以及最近兴起的服务网络等等。

核心的负载均衡模式随着云计算的发展而不断发展,而且,随着大型 web 服务商致力于让负载均衡技术更可控和更灵活,这项技术会持续发展下去。


via: https://opensource.com/article/18/10/internet-scale-load-balancing

作者:Laura Nolan 选题:lujun9972 译者:BeliteX 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

DNS 轮询将多个服务器映射到同一个主机名,并没有为这里展示的魔法做更多的工作。

如果你的后端服务器是由多台服务器构成的,比如集群化或者镜像的 Web 或者文件服务器,通过负载均衡器提供了单一的入口点。业务繁忙的大型电商在高端负载均衡器上花费了大量的资金,用它来执行各种各样的任务:代理、缓存、状况检查、SSL 处理、可配置的优先级、流量整形等很多任务。

但是你并不需要做那么多工作的负载均衡器。你需要的是一个跨服务器分发负载的简单方法,它能够提供故障切换,并且不太在意它是否高效和完美。DNS 轮询和使用轮询的子域委派是实现这个目标的两种简单方法。

DNS 轮询是将多台服务器映射到同一个主机名上,当用户访问 foo.example.com 时多台服务器都可用于处理它们的请求,使用的就是这种方式。

当你有多个子域或者你的服务器在地理上比较分散时,使用轮询的子域委派就比较有用。你有一个主域名服务器,而子域有它们自己的域名服务器。你的主域名服务器将所有的到子域的请求指向到它们自己的域名服务器上。这将提升响应时间,因为 DNS 协议会自动查找最快的链路。

DNS 轮询

轮询和 旅鸫鸟 robins 没有任何关系,据我相熟的图书管理员说,它最初是一个法语短语,ruban rond、或者 round ribbon。很久以前,法国政府官员以不分级的圆形、波浪线、或者直线形状来在请愿书上签字,以盖住原来的发起人。

DNS 轮询也是不分级的,简单配置一个服务器列表,然后将请求转到每个服务器上。它并不做真正的负载均衡,因为它根本就不测量负载,也没有状况检查,因此如果一个服务器宕机,请求仍然会发送到那个宕机的服务器上。它的优点就是简单。如果你有一个小的文件或者 Web 服务器集群,想通过一个简单的方法在它们之间分散负载,那么 DNS 轮询很适合你。

你所做的全部配置就是创建多条 A 或者 AAAA 记录,映射多台服务器到单个的主机名。这个 BIND 示例同时使用了 IPv4 和 IPv6 私有地址类:

fileserv.example.com. IN A 172.16.10.10
fileserv.example.com. IN A 172.16.10.11
fileserv.example.com. IN A 172.16.10.12

fileserv.example.com. IN AAAA fd02:faea:f561:8fa0:1::10
fileserv.example.com. IN AAAA fd02:faea:f561:8fa0:1::11
fileserv.example.com. IN AAAA fd02:faea:f561:8fa0:1::12

Dnsmasq 在 /etc/hosts 文件中保存 A 和 AAAA 记录:

172.16.1.10 fileserv fileserv.example.com
172.16.1.11 fileserv fileserv.example.com
172.16.1.12 fileserv fileserv.example.com
fd02:faea:f561:8fa0:1::10 fileserv fileserv.example.com
fd02:faea:f561:8fa0:1::11 fileserv fileserv.example.com
fd02:faea:f561:8fa0:1::12 fileserv fileserv.example.com

请注意这些示例都是很简化的,解析完全合格域名有多种方法,因此,关于如何配置 DNS 请自行学习。

使用 dig 命令去检查你的配置能否按预期工作。将 ns.example.com 替换为你的域名服务器:

$ dig @ns.example.com fileserv A fileserv AAA

它将同时显示出 IPv4 和 IPv6 的轮询记录。

子域委派和轮询

子域委派结合轮询要做的配置会更多,但是这样有一些好处。当你有多个子域或者地理位置比较分散的服务器时,就应该去使用它。它的响应时间更快,并且宕机的服务器不会去响应,因此客户端不会因为等待回复而被挂住。一个短的 TTL,比如 60 秒,就能帮你做到。

这种方法需要多台域名服务器。在最简化的场景中,你需要一台主域名服务器和两个子域,每个子域都有它们自己的域名服务器。在子域服务器上配置你的轮询记录,然后在你的主域名服务器上配置委派。

在主域名服务器上的 BIND 中,你至少需要两个额外的配置,一个区声明以及在区数据文件中的 A/AAAA 记录。主域名服务器中的委派应该像如下的内容:

ns1.sub.example.com. IN A 172.16.1.20
ns1.sub.example.com. IN AAAA fd02:faea:f561:8fa0:1::20
ns2.sub.example.com. IN A 172.16.1.21
ns2.sub.example.com. IN AAA fd02:faea:f561:8fa0:1::21

sub.example.com. IN NS ns1.sub.example.com.
sub.example.com. IN NS ns2.sub.example.com.

接下来的每台子域服务器上有它们自己的区文件。在这里它的关键点是每个服务器去返回它自己的 IP 地址。在 named.conf 中的区声明,所有的服务上都是一样的:

zone "sub.example.com" {
    type master;
    file "db.sub.example.com";
};

然后数据文件也是相同的,除了那个 A/AAAA 记录使用的是各个服务器自己的 IP 地址。SOA 记录都指向到主域名服务器:

; first subdomain name server
$ORIGIN sub.example.com.
$TTL 60
sub.example.com  IN SOA ns1.example.com. admin.example.com. (
        2018123456      ; serial
        3H              ; refresh
        15              ; retry
        3600000         ; expire
)

sub.example.com. IN NS ns1.sub.example.com.
sub.example.com. IN A  172.16.1.20
ns1.sub.example.com.  IN AAAA  fd02:faea:f561:8fa0:1::20
; second subdomain name server
$ORIGIN sub.example.com.
$TTL 60
sub.example.com  IN SOA ns1.example.com. admin.example.com. (
        2018234567      ; serial
        3H              ; refresh
        15              ; retry
        3600000         ; expire
)

sub.example.com. IN NS ns1.sub.example.com.
sub.example.com. IN A  172.16.1.21
ns2.sub.example.com.  IN AAAA  fd02:faea:f561:8fa0:1::21

接下来生成子域服务器上的轮询记录,方法和前面一样。现在你已经有了多个域名服务器来处理到你的子域的请求。再说一次,BIND 是很复杂的,做同一件事情它有多种方法,因此,给你留的家庭作业是找出适合你使用的最佳配置方法。

在 Dnsmasq 中做子域委派很容易。在你的主域名服务器上的 dnsmasq.conf 文件中添加如下的行,去指向到子域的域名服务器:

server=/sub.example.com/172.16.1.20
server=/sub.example.com/172.16.1.21
server=/sub.example.com/fd02:faea:f561:8fa0:1::20
server=/sub.example.com/fd02:faea:f561:8fa0:1::21

然后在子域的域名服务器上的 /etc/hosts 中配置轮询。

获取配置方法的详细内容和帮助,请参考这些资源:

通过来自 Linux 基金会和 edX 的免费课程 "Linux 入门" 学习更多 Linux 的知识。


via: https://www.linux.com/learn/intro-to-linux/2018/3/simple-load-balancing-dns-linux

作者:CARLA SCHRODER 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

负载均衡器如何帮助你解决分布式系统的复杂性。

Ship with tug

原生云应用旨在利用分布式系统的性能、可扩展性和可靠性优势。不幸的是,分布式系统往往以额外的复杂性为代价。由于你程序的各个组件跨网络分布,并且这些网络有通信障碍或者性能降级,因此你的分布式程序组件需要能够继续独立运行。

为了避免程序状态的不一致,分布式系统设计应该有一个共识,即组件会失效。没有什么比在网络中更突出了。因此,在其核心,分布式系统在很大程度上依赖于负载平衡——请求分布于两个或多个系统,以便在面临网络中断时具有弹性,并在系统负载波动时水平缩放时。

随着分布式系统在原生云程序的设计和交付中越来越普及,负载平衡器在现代应用程序体系结构的各个层次都影响了基础设施设计。在大多数常见配置中,负载平衡器部署在应用程序前端,处理来自外部世界的请求。然而,微服务的出现意味着负载平衡器可以在幕后发挥关键作用:即管理服务之间的流。

因此,当你使用原生云程序和分布式系统时,负载均衡器将承担其他角色:

  • 作为提供缓存和增加安全性的反向代理,因为它成为外部客户端的中间人。
  • 作为通过提供协议转换(例如 REST 到 AMQP)的 API 网关
  • 它可以处理安全性(即运行 Web 应用程序防火墙)。
  • 它可能承担应用程序管理任务,如速率限制和 HTTP/2 支持。

鉴于它们的扩展能力远大于平衡流量, 负载平衡器 load balancer 可以更广泛地称为 应用交付控制器 Application Delivery Controller (ADC)。

开发人员定义基础设施

从历史上看,ADC 是由 IT 专业人员购买、部署和管理的,最常见运行企业级架构的应用程序。对于物理负载平衡器设备(如 F5、Citrix、Brocade等),这种情况在很大程度上仍然存在。具有分布式系统设计和临时基础设施的云原生应用要求负载平衡器与它们运行时的基础设施 (如容器) 一样具有动态特性。这些通常是软件负载均衡器(例如来自公共云提供商的 NGINX 和负载平衡器)。云原生应用通常是开发人员主导的计划,这意味着开发人员正在创建应用程序(例如微服务器)和基础设施(Kubernetes 和 NGINX)。开发人员越来越多地对负载平衡 (和其他) 基础设施的决策做出或产生重大影响。

作为决策者,云原生应用的开发人员通常不会意识到企业基础设施需求或现有部署的影响,同时要考虑到这些部署通常是新的,并且经常在公共或私有云环境中进行部署。云技术将基础设施抽象为可编程 API,开发人员正在定义应用程序在该基础设施的每一层的构建方式。在有负载平衡器的情况下,开发人员会选择要使用的类型、部署方式以及启用哪些功能。它们以编程的方式对负载平衡器的行为进行编码 —— 随着程序在部署的生存期内增长、收缩和功能上进化时,它如何动态响应应用程序的需要。开发人员将基础设施定义为代码 —— 包括基础设施配置及其运维。

开发者为什么定义基础设施?

编写如何构建和部署应用程序的代码实践已经发生了根本性的转变,它体现在很多方面。简而言之,这种根本性的转变是由两个因素推动的:将新的应用功能推向市场所需的时间(上市时间)以及应用用户从产品中获得价值所需的时间(获益时间)。因此,新的程序写出来就被持续地交付(作为服务),无需下载和安装。

上市时间和获益时间的压力并不是新的,但由于其他因素的加剧,这些因素正在加强开发者的决策权力:

  • 云:通过 API 将基础设施定义为代码的能力。
  • 伸缩:需要在大型环境中高效运维。
  • 速度:马上需要交付应用功能,为企业争取竞争力。
  • 微服务:抽象框架和工具选择,进一步赋予开发人员基础设施决策权力。

除了上述因素外,值得注意的是开源的影响。随着开源软件的普及和发展,开发人员手中掌握了许多应用程序基础设施 - 语言、运行时环境、框架、数据库、负载均衡器、托管服务等。微服务的兴起使应用程序基础设施的选择民主化,允许开发人员选择最佳的工具。在选择负载平衡器的情况下,那些与云原生应用的动态特质紧密集成并响应的那些人将超人一等。

总结

当你在仔细考虑你的云原生应用设计时,请与我一起讨论“在云中使用 NGINX 和 Kubernetes 进行负载平衡”。我们将检测不同公共云和容器平台的负载平衡功能,并通过一个宏应用的案例研究。我们将看看它是如何被变成较小的、独立的服务,以及 NGINX 和 Kubernetes 的能力是如何拯救它的。


作者简介:

Lee Calcote 是一位创新思想领袖,对开发者平台和云、容器、基础设施和应用的管理软件充满热情。先进的和新兴的技术一直是 Calcote 在 SolarWinds、Seagate、Cisco 和 Pelco 时的关注重点。他是技术会议和聚会的组织者、写作者、作家、演讲者,经常活跃在技术社区。


via: https://www.oreilly.com/learning/developer-defined-application-delivery

作者:Lee Calcote 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出