如何使用Digital Ocean DNS和Nginx设置全局负载平衡?

AJB*_*AJB 28 dns global load-balancing nginx digital-ocean

更新:请参阅我在下面提供的答案,了解我最终在AWS上设置的解决方案.

我目前正在尝试使用有关如何在Digital Ocean上为我的应用服务器最佳实现全局负载平衡层的方法,还有一些我尚未整理的部分.

目标

通过将所有连接路由到SFO,NYC,LON和最终新加坡最近的"服务器集群",为我的用户提供高可用性服务.

另外,我最终希望通过编写一个可以监视,扩展和修复系统上任何服务器的守护程序来自动维护它.或者我将结合各种服务来实现相同的自动化目标.首先,我需要弄清楚如何手动完成.

堆栈

  1. Ubuntu 14.04
  2. Nginx 1.4.6
  3. 的node.js
  4. 来自Compose.io的 MongoDB (原名MongoHQ)

全球域名细分

一旦我完成了所有工作,我的域名将如下所示:

**GLOBAL**
global-balancing-1.myapp.com
global-balancing-2.myapp.com
global-balancing-3.myapp.com

**NYC**
nyc-load-balancing-1.myapp.com
nyc-load-balancing-2.myapp.com
nyc-load-balancing-3.myapp.com

nyc-app-1.myapp.com
nyc-app-2.myapp.com
nyc-app-3.myapp.com

nyc-api-1.myapp.com
nyc-api-2.myapp.com
nyc-api-3.myapp.com

**SFO**
sfo-load-balancing-1.myapp.com
sfo-load-balancing-2.myapp.com
sfo-load-balancing-3.myapp.com

sfo-app-1.myapp.com
sfo-app-2.myapp.com
sfo-app-3.myapp.com

sfo-api-1.myapp.com
sfo-api-2.myapp.com
sfo-api-3.myapp.com

**LON**
lon-load-balancing-1.myapp.com
lon-load-balancing-2.myapp.com
lon-load-balancing-3.myapp.com

lon-app-1.myapp.com
lon-app-2.myapp.com
lon-app-3.myapp.com

lon-api-1.myapp.com
lon-api-2.myapp.com
lon-api-3.myapp.com
Run Code Online (Sandbox Code Playgroud)

然后,如果有任何给定层上的任何应变,在任何给定的区域,我就可以旋转了一个新的液滴助阵:nyc-app-4.myapp.com,lon-load-balancing-5.myapp.com,等...

现行工作方法

  • (最少)三个global-balancing服务器接收所有流量.这些服务器是$geoip_city_continent_code平衡的,如本文(坦率地说令人困惑)文章所示:如何配置DNS循环负载平衡.

  • 使用Nginx GeoIP模块MaxMind GeoIP数据 ,任何给定请求的来源都将确定为 global-balancing.

  • 所述load-balancing然后层将请求路由到nyc-load-balancing-1所述服务器上sfo-load-balancing-3相应的集群的层:lon-load-balancing-2,load-balancing, nyc-app-2,等.该层也是液滴的(最小)三人.

  • 区域sfo-api-1然后层将请求路由到 lon-api-3在该应用或API层服务器:global-balancing, global-balancing,global-balancing,等...

Nginx功夫的详细信息可以在本教程中找到: Villiage Idiot:在AWS上使用GSLB /反向代理设置Nginx.有关Nginx负载平衡的更多常规信息可 在此处此处获得.

问题

我把app服务器放在哪里?

令我感到奇怪的是,我将它们全部放在一个地方,或者将这一层传播到全球各地.比方说,我把它们都放在纽约市.然后来自法国的人来到我的域名.请求将从法国,到纽约,然后被路由回LON.或者,如果我将每个中的一个放入SFO,NYC和LON,那么来自多伦多(Parkdale,代表)的用户是否仍然可以发送最终转到LON但仅被路由回纽约的请求?

后续请求是否被路由到同一个IP?

同样,如果来自多伦多的用户发送了一个api层确定应该去纽约的请求,那么来自该来源的下一个请求是否会直接转到纽约市,或者它仍然是抽奖的运气,它将会到达最近的global-balancing服务器(NYC)在这种情况下).

会议怎么样?

我已配置nyc-app-4.myapp.com为使用ip_hash; 指令因此它会将用户引导到相同lon-load-balancing-5.myapp.comglobal-balancing端点(在我的情况下是一个节点进程)但是如果有的话,全局平衡将如何影响这个?

任何DNS示例?

我不是一个DNS专家(我目前正试图弄清楚为什么我的CNAME记录没有解析)但是我提供了一个可靠的例子,我是一个快速的研究.有没有人之前经历过这个过程,并且可以提供DNS记录成功设置的样本?

SSL/TLS怎么样?

我是否需要为每台服务器提供证书,或仅为三台$geoip_city_continent_code服务器提供证书,因为这是唯一面向公众的网关?

如果你读完这整件事,那就用蛋糕奖励自己吧.在此先感谢您的帮助.

Bra*_*rad 21

目标:通过将所有连接路由到SFO,NYC,LON和最终新加坡最近的"服务器集群",为我的用户提供高可用性服务.

然后,全局平衡层将请求路由到最少连接的服务器......

如果我正确地读取您的配置,您实际上是从全局平衡器代理到每个区域的平衡器.这不符合您将用户路由到最近区域的目标.

我知道有三种方法可以满足您的需求:

  1. 30x重定向
    您的全局平衡器接收HTTP请求,然后根据IP地址将其重定向到其认为请求来自的区域内或附近的服务器组.这听起来像你想要设置的.此方法对某些应用程序具有副作用,并且还增加了用户获取数据所需的时间,因为您增加了大量开销.只有当您重定向到的资源非常大时才有意义,并且本地区域群集将能够更有效地提供服务.

  2. Anycast(利用BGP路由)
    这就像Akamai这样的大玩家用于他们的CDN.基本上,互联网上有多个服务器具有完全相同的可路由IP地址.假设我在多个地区都有服务器,它们的IP地址为192.0.2.1.如果我在美国并尝试连接到192.0.2.1,并且有人在欧洲试图连接到192.0.2.1,那么我们可能会被路由到最近的服务器.这使用互联网自己的路由来查找流量的最佳路径(基于网络条件).不幸的是,你不能只使用这种方法.您需要自己的AS号和物理硬件.如果你找到一个VPS提供商,让你有一大块他们的Anycast块,请告诉我!

  3. 地理DNS
    有些DNS提供商提供的服务通常以"地理DNS"的形式销售.他们在任播地址上托管了一堆DNS服务器,可以将流量路由到最近的服务器.如果客户端查询欧洲DNS服务器,则应返回欧洲区域服务器的地址,而不是其他区域的某些服务器.地理DNS服务有很多变化.其他人只是简单地维护一个地理IP数据库并返回他们认为更接近的区域的服务器,就像重定向方法一样,但是在发出HTTP请求之前用于DNS.这通常是价格和易用性的好选择.

后续请求是否被路由到同一个IP?

许多负载均衡器具有"粘性"选项,即来自同一网络地址的请求应路由到同一终端服务器(前提是终端服务器仍在运行).

会议怎么样?

这正是你想要那种粘性的原因.说到会话数据,您将不得不找到一种方法来使所有服务器保持最新状态.实际上,这并不总是得到保证.你如何处理它取决于你的应用程序.您是否可以保留Redis实例或其他任何内容,以便您的所有服务器能够可靠地从世界各地进行攻击?你真的需要每个地区的会话数据吗?或者您可以让主应用程序服务器在一个位置处理会话数据吗?

任何DNS示例?

为这些发布单独的问题.每个人的"成功设置"看起来都不同.

SSL/TLS怎么样?

如果您要代理数据,则只有全局平衡器需要处理HTTPS.如果您正在重定向,那么所有服务器都需要处理它.

  • 哈.这是一个很棒的头衔!我正在计划它.有很多笔记.我的工作头衔是"倒下我们去的地方!" 或"啤酒预算全球高可用性".我喜欢你的.无论如何,OpsWorks似乎在自动化和定制之间取得了适当的平衡,所以希望这是我的旋风之旅的结束,我将很快能够写出我的发现.一旦我准备好阅读草稿,我会把它发给你. (2认同)

AJB*_*AJB 12

工作解决方案

在过去的几个月中,我已经疯狂地驾驭整个Global-HA设置.很有趣,我终于找到了一个非常好的装备,并且与上面提到的问题完全不同.

我还打算用教程形式写这篇文章,但是当我进入最后的冲刺阶段以便在明年初推出我的应用程序时,时间很少,所以这里是我最终的工作装备的快速概述.


概观

我最终将整个部署移至AWS.我喜欢数字海洋,但坦率的现实是,在一个屋檐下提供的服务方面,AWS比他们(以及每个人)都要轻松多年.我的每月费用略有上升,但是一旦我完成了调整和精简,我最终得到的解决方案是,对于最基本的部署,每个区域的成本约为75美元/月(ELB背后的2个实例).一个新的区域可以在大约30分钟内旋转并部署.


全球平衡

我很快发现(感谢上面的@Brad的回答)试图启动我自己的全局平衡DNS层是疯了.找到像这样的层是如何工作的,这是一个很有趣的地方,但是没有在飞机上刮我的指关节,在世界各地安装价值数百万美元的设备,这是不可能滚动我的拥有.

当我终于找到了我想要的东西时,我找到了我最好的朋友:AWS Route 53.它提供了一个强大的DNS网络,全球大约有50多个节点,能够做一些非常酷的路由技巧,如基于位置的路由,基于延迟的路由(这有点棒),以及AWS Alias记录"自动"路由流量到您将使用的其他AWS服务(与ELB一样用于负载平衡).

我最终使用了基于延迟的路由,将全局流量引导到最近的区域Elastic Load Balancer,在任何给定区域中都有一个Auto-Scaling Group.

我会留给你做其他供应商的功课:www.f5.com,www.dyn.com,www.akamai.com,www.dnsmadeeasy.com.根据您的需要,可能有更好的解决方案,但这对我来说非常有效.


内容分发网络

Route 53 非常适合AWS Cloudfront集成.我设置了一个S3存储桶,我用它来存储我的用户将上传的所有静态媒体文件,并且我已经配置了一个Cloudfront发行版来源于我的media.myapp.comS3存储桶.还有其他CDN提供商,您的购物也是如此.但Cloudfront获得了相当不错的评论,而且设置也很简单.


负载平衡和SSL终止

我目前正在使用AWS Elastic Load Balancer来平衡我的应用程序实例的负载,这些实例位于Auto-Scaling组中.该请求首先由ELB接收,此时SSL终止并且请求被传递到Auto-Scaling组中的实例.

注意: ELB的一个巨大警告是,有点讽刺的是,它不能很好地处理大量尖峰.ELB最多可能需要15分钟才能触发自身的放大事件,同时创建500次/超时.据说可以很好地处理稳定,持续的流量增加,但是如果你遇到尖峰,它可能会让你失望.如果你知道你会受到打击,你就可以"提前打电话",AWS会为你热身你的ELB,这对于AWS的本质来说是非常荒谬和反模式的,但是我成像他们要么正在努力它,或忽略它,因为它不是一个大问题.如果ELB不适合您,您可以随时启动自己的HAProxyNginx负载平衡层.


Auto-Scaling Group

每个区域都有一个ASG,可以在负载超过某个指标时进行编程:

IF CPU > 90% FOR 5 MINUTES: SCALEUP
IF CPU < 70% FOR 5 MINUTES: SCALEDN
Run Code Online (Sandbox Code Playgroud)

我还没有完成ELB/ASG组合的步伐.这是我的待办事项列表中的一点点,但我知道有很多其他人使用此设置,它似乎没有任何重大的性能问题.

在我看来,Auto-Scaling Group的配置有点令人费解.这实际上是一个三步过程:

  1. 根据自己的喜好创建AMI.
  2. 创建使用您创建的AMI的启动配置.
  3. 创建一个Auto-Scaling组,该组使用您创建的启动配置来确定要为任何给定的SCALEUP事件启动的AMI和实例类型.

要在任何实例启动时处理配置和应用程序部署,请使用"用户数据"字段输入将在任何给定实例启动时运行的脚本.这可能是历史上最糟糕的命名法."用户数据"如何描述只有作者知道的启动脚本.无论如何,这就是你坚持处理所有apt-gets,mkdirs,git克隆等的脚本的地方.


实例和内部平衡

我还使用Nginx添加了一个额外的"内部平衡层",允许我"扁平化"我的所有Node.js应用程序(app.myapp.com,api.myapp.com,mobile.myapp.com,www. myapp.com,etc.myapp.com)在每个实例上.当实例收到从ELB传递给它的请求时,Nginx会处理将请求路由到任何给定应用程序的正确Node.js端口.有点像穷人的集装箱化.这有一个额外的好处,任何时候我的一个应用程序需要与另一个应用程序(如何app.需要发送请求api.)通过它完成,localhost:XXXX而不必通过AWS网络或互联网本身.

此设置还可以通过消除任何空闲基础架构来最大限度地利用我的资源,如果它所承载的应用层恰好接收到轻量级流量.它还避免了为每个应用程序提供和ELB/ASG组合的需求,从而节省了更多现金.

我使用这种设置没有遇到任何问题或警告,但是在健康检查方面需要有一个解决方法(见下文).

还有一个很好的好处,即所有实例都具有IAM角色,这意味着您的AWS信誉在出生时被"烘焙"到每个实例,并可通过您的ENV vars访问.AWS'自动'为您转动您的信誉.非常安全,非常酷.


健康检查

如果你走上述设置的路线,将所有应用程序平放在一个盒子上并运行内部负载均衡器,那么你需要创建一个小实用程序来处理ELB健康检查.我做的是创建一个名为ping.myapp.com的附加应用程序.然后我配置了我的ELB运行状况检查以将任何运行状况检查发送到运行我的ping应用程序的端口,如下所示:

Ping Protocol: HTTP
Ping Port:     XXXX
Ping Path:     /ping
Run Code Online (Sandbox Code Playgroud)

这会将所有运行状况检查发送给我的小ping帮助程序,而这个帮助localhost:XXXX/ping程序又会对驻留在该实例上的所有应用程序进行命中.如果他们都返回200响应,我的ping应用程序然后返回对ELB运行状况检查的200响应,并且实例再生存30秒.

注意:如果您使用的是ELB,请勿使用Auto-Scaling Health Checks.使用ELB运行状况检查.这有点令人困惑,我认为它们是相同的,它们不是.您可以选择启用其中一个.和ELB一起去.


数据层

我的设置中明显缺少的一件事是数据层.我使用Compose.io作为托管数据层提供程序,并在AWS上部署,因此我的应用程序层和数据层之间的延迟非常低.我已经做了一些关于如何在全球范围内推出数据层的初步调查,并发现它非常复杂 - 并且非常昂贵 - 所以我把它作为一个尚未解决的问题从我的列表中踢出来.最糟糕的情况是,我将仅在美国东部运行我的数据层并加强硬件.这不是世界上最糟糕的事情,因为我的API是严格的线上JSON数据,因此平均响应相对较小.但我可以看到,如果我到达那里,这将成为全球规模巨大的瓶颈.如果有人在这一层有任何意见,我很想听听你的意见.


当当!

啤酒预算的全球高可用性.我花了6个月才搞清楚.

喜欢听到任何恰好阅读此内容的人的意见或想法.