使用DNS和Javascript实现节点间的负载均衡

3
让我们进行一次思想实验(显然,这不是一个真实的情况)。假设:
  • 我有一个巨大的服务器群。巨大意味着:数百万个节点。
  • 每个节点都不可靠:它经常会(并且将)离线,正如对等网络中的节点不断上下线。
  • 每个节点都很弱(它的带宽和资源非常有限)。
  • 每个服务器都是公开可访问的(所以不要担心NAT翻译器等问题)。
  • 每个服务器都公开了WebSocket接口,能够通过某些协议提供一组静态资源(例如图像、视频等)。
现在,假设我想使用这个群集来保持一个非常受欢迎的网站(数百万用户)的在线状态(静态部分)。我做的是:
  • 我在每个页面中嵌入一个javascript代码,以连接到我的网络中的一堆服务器(例如16个)。
  • 用户成功连接到其中一些对等端,选择最快的对等端,通过WebSocket加载资源,然后显示它们。
  • (现在先不考虑安全性。)
  • 非常紧密的超时机制允许在合理的时间内无法连接到任何客户端时回退到标准的Web服务器。
我使用一组对等节点进行了实际试验,并且运行得很顺畅。如果对等节点靠近我的当前位置,则从对等节点加载资源实际上比从我的服务器加载更快。非常好。
现在,我想考虑如何通过DNS在所有这些服务器之间进行负载平衡。当然,依靠轮询DNS将是自杀行为:我绝对不能在其中有数百万个A记录的单个域中。
所以这是我的想法,我想知道原则上是否可以工作。
  • 我运行自己的DNS服务器,例如使用NodeJS和dnsd。
  • 每次我的DNS被要求提供像something.mywebsite.com这样的子域时,它会返回一个随机的、当前在线的服务器IP地址。
  • 要连接到服务器,我的网页上的脚本只需随机化子域即可。
  • 我可以使用某些客户端机制缓存最后使用的子域,以便在不严格必要时利用缓存的DNS记录并避免使我的DNS服务器过度负载。
在我看来,这应该可以工作,但我可以看到一些问题。我首先想到的是:缓存DNS服务器会对我生气吗?例如:Google的4.4.4.4将接收到数百万个来自我的域的不同随机子域的请求。它最终会阻止或停止响应或做出其他反应吗?
这样做还可能存在其他问题吗?有更好的方法吗?从理论上讲,这完全不可行吗?

第一遍看,我认为你只是描述了CDN网络的工作方式! ;) - Michael B
太棒了:D 当你再次发现轮子时,这总是一个好消息。你浪费了一些时间,但至少你知道它能工作! - Matteo Monti
说实话,那是一个懒散的周六下午(今天是周六吧?!),所以我可能错过了一两个重要的点,但CDN网络确实以类似的方式操作DNS记录,以获取最接近您的内容。 - Michael B
@MichaelB 让我尽可能地总结一下:我的方法的缺点是,我使用自己的权威 DNS 将随机子域名指向随机服务器,每当新用户加载资源时都会这样做。这是对于我的域名而言数以百万计的子域名。这样做可行吗? - Matteo Monti
1个回答

1
DNS的核心概念是,对于每个可寻址的IP地址,您都有一个相应的A记录。这符合逻辑,因为每个服务器只能有一个主机名,而DNS就是关于主机名的。
但是,有时您不希望主机名成为人们连接的名称,因此您会使用CNAME,它是别名的规范名称(在这种情况下,规范表示权威),而不是A记录的别名,以避免混淆。
因此,如果您正在查看Example.com,则可能具有:
fred  IN  A 192.168.0.1
alice IN  A 192.168.0.2 
bob   IN  A 192.168.0.3
www   IN  CNAME bob.example.com
web   IN  CNAME www.example.com

所以,除非您实际上部署了拥有独特IP地址的数百万台服务器(如果是这种情况,我很好奇您从哪里得到它们和您是谁!),否则如果您有x个主机,并且希望为它们提供可连接的主机名,则实际上希望配置CNAME记录。 CNAME记录的一个有趣之处是,您可以使用它们设置多个重定向,因此您可以使用它们分层层次结构,这是A记录无法做到的。如果您遵循DNS规则,则Google等公司不应该对您使用的任何名称有任何问题。理解DNS复杂性的绝佳起点是《Dragonfly book》。编辑后添加:如果这些是互联网上的机器,则可以为每个机器提供A记录/主机名(我假设这就是您所说的子域)。没有理由您不能为每个A记录提供CNAME记录。

从DNS的角度来看,我认为你可以通过这种方式提供负载均衡,但在发送CNAME记录之前,你可能需要进行测试以确保端点在线。但使用CNAME记录进行负载平衡的概念肯定不是新的,例如CDN。


首先,正如我所说,这是纯虚构。我没有一百万台服务器:D 其次,服务器将拥有不同的IP地址。如果您愿意,您可以将它们描绘为志愿者和他们的笔记本电脑的人口,就像点对点网络一样。 - Matteo Monti
现在,如果我理解正确的话,您建议我为每个服务器分配一些子域(即一些百万个记录),并将其指向服务器的IP地址。然后,我可以使用CNAME记录来创建“别名”。我说的对吗? - Matteo Monti
如果我理解得正确的话,您能否明确回答一下我使用随机子域名连接到随机服务器的想法?这个想法是:1)JavaScript 随机生成一个子域名(比如“cjhkdjsfh.mywebsite.com”)。2)它连接到该域名。3)我的权威 DNS 将返回一个 CNAME 到一个随机对等方的子域名。 - Matteo Monti
这是我认为我可以进行负载均衡的方式,但这意味着每当一个新用户打开我的网页时,都会生成一个随机子域的新CNAME记录。这样做可行吗? - Matteo Monti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接