我有一个奇怪的想法 - 让多个人/组织托管同一个应用程序,并让他们的所有节点都可以通过单个域名访问。这样可以建立一个真正分布式的社交网络,而不会牺牲可用性(即用户不必记住不同的提供商网址,然后当一个提供商出现故障时,切换到另一个提供商)
为了实现这一点,我认为可以使用具有多个 IP 的 DNS 记录。
那么,单个 DNS A 记录可以容纳多少个 IP?这个答案说大约是 30,但那里的用例不同。对于上述场景,我不会关心某个 ISP 是否只缓存 30,只要另一个 ISP 缓存另外 30,依此类推。
答案1
免责声明:无意冒犯,但这确实是一个糟糕的想法。我不建议任何人在现实生活中这样做。
但是如果你给一个无聊的 IT 人员一个实验室,有趣的事情就会发生!
在本实验中,我使用了在 Server 2012 R2 上运行的 Microsoft DNS 服务器。由于在 Active Directory 中托管 DNS 区域的复杂性,我创建了一个名为 testing.com 的新主区域,该区域不是AD 集成。
使用此脚本:
$Count = 1
for ($x = 1; $x -lt 256; $x++)
{
for ($y = 1; $y -lt 256; $y++)
{
for ($z = 1; $z -lt 256; $z++)
{
Write-Host "1.$x.$y.$z`t( $Count )"
$Count++
dnscmd . /RecordAdd testing.com testing A 1.$x.$y.$z
}
}
}
我继续为该名称创建了 65025 条主机记录,并且没有任何错误,这些记录testing.testing.com.
几乎涵盖了从 1.1.1.1 到 1.1.255.255 的每个 IPv4 地址。
然后,我想确保我可以在不出现错误的情况下突破 65536(2^16 位)个 A 记录总数,而且我可以,所以我认为我可能可以一直达到 16581375(1.1.1.1 到 1.255.255.255,)但我不想坐在这里看着这个脚本整晚运行。
因此,我认为可以肯定地说,您可以向服务器上具有不同 IP 的同名区域添加的 A 记录数量没有实际限制。
但实际上工作从客户的角度来看?
以下是 Wireshark 查看的从我的客户端获得的信息:
(在新浏览器选项卡中打开图像以查看完整尺寸。)
如您所见,当我从客户端使用 nslookup 或 ping 时,它会自动发出两个查询 - 一个 UDP 和一个 TCP。如您所知,我最多可以塞入 UDP 数据报 512 字节,因此一旦超过该限制(例如 20-30 个 IP 地址),就必须改用 TCP。但即使使用 TCP,我也只能获得 testing.testing.com 的一小部分 A 记录。每个 TCP 查询返回 1000 条记录。A 记录列表会随着每个连续查询正确地轮换 1,就像您期望循环 DNS 的工作方式一样。循环处理所有这些记录需要数百万个查询。
我不知道这将如何帮助你建立具有大规模可扩展性、弹性的社交媒体网络,但无论如何,这是你的答案。
编辑:在您的后续评论中,您问我为什么认为这通常是一个坏主意。
假设我是一名普通的互联网用户,我想连接到您的服务。我在 Web 浏览器中输入 www.bozho.biz。我电脑上的 DNS 客户端返回了 1000 条记录。但是,不幸的是,列表中的前 30 条记录没有响应,因为 A 记录列表没有保持更新,或者可能是发生了影响互联网的大规模中断。假设我的 Web 浏览器对每个 IP 的超时时间为 5 秒,之后才会继续尝试下一个 IP。所以现在我坐在这里盯着旋转的沙漏等了 2 分半钟,等待您的网站加载。没人有时间这样做。我只是假设我的 Web 浏览器或我用来访问您的服务的任何应用程序甚至会尝试超过前 4 或 5 个 IP 地址。它可能不会。
如果您使用自动清理并允许对 DNS 区域进行未经验证或匿名的更新,以期保持 A 记录列表的最新状态……想象一下这是多么不安全!即使您设计了某种系统,客户端需要事先从您那里获得的客户端 TLS 证书才能更新区域,地球上任何地方的一个受感染的客户端都会启动僵尸网络并破坏您的服务。传统 DNS 本身就非常不安全,没有众包。
巨大的带宽使用和浪费。如果每个 DNS 查询都需要 32 千字节或更多的带宽,那么扩展性就很差。
DNS 轮询不能替代适当的负载平衡。它无法从某个节点宕机或中途不可用时恢复。如果用户所连接的节点宕机,您会指示用户执行 ipconfig/flushdns 吗?这类问题已经通过 GSLB 和 Anycast 等技术得到解决。
ETC。
答案2
要回答上述问题(“单个 DNS A 记录可以保存多少个 IP?”),答案很简单:单个记录只保存一个地址。但是,同一个名称A
可以有多条记录。A
答案3
每个 IPv4 地址将在回复中占用 16 个字节。每个 IPv6 地址将在回复中占用 28 个字节。
强烈建议您确保回复不超过 512 字节。这将允许大约 25 个 IPv4 地址和 14 个 IPv6 地址(考虑到您还需要数据包中的其他一些信息)。确切的限制取决于您的域名的长度。
如果您同时拥有 25 个 IPv4 地址和 14 个 IPv6 地址,那么您将依赖客户端在单独的查询中请求 IPv4 和 IPv6 地址。如果客户端在单个查询中请求两种类型的地址(这种情况很少见),那么您就必须降低请求数量。
如果回复大小超过 512 字节,如果客户端和服务器支持 EDNS,它仍可能通过 UDP 工作。如果没有 EDNS,客户端将收到截断的回复,并且必须通过 TCP 重试。这会使通信从 1 次往返增加到 4 次。但更糟糕的是,有时配置错误会阻止 DNS 通过 TCP 工作。
即使您可以将超过 14 个地址塞入回复而不会在 DNS 层造成问题,它也不太可能非常有用。客户端在放弃一个地址并继续下一个地址之前使用的超时时间通常很长。
即使只等待一次超时也会导致糟糕的用户体验。如果客户端必须经过 14 个地址才能获得响应,则用户必须等待 13 次超时。
答案4
其他人提到了这一点,但从实际角度来看,硬限制是 512 字节的 UDP 数据包大小限制。虽然在检测到截断时可以切换到 TCP,但实际上许多/大多数客户端不会这样做(可以说它们不应该这样做;这会给大多数应用程序带来糟糕的用户体验,我只希望区域传输或其他特殊用途的查找支持 TCP)。因此,您正在查看 IPv4(A 记录)的地址限制约为 30 个,而 IPv6(AAAA)的地址限制则略少一些,因为它们更大。域名的长度会减少这一点,并将进一步限制数量。