(我做这些东西已经有一段时间了。请不要盲目地假设所有下面的细节都是正确的。但我希望我不是太尴尬的错误。:))
正如前面的回答所说,Minecraft 客户端 (as of 1.3.1) 支持使用服务名称 _minecraft 和协议名称 _tcp 查找 SRV record,这意味着如果您的区域文件看起来像这样......
arboristal.com. 86400 IN A <your IP address>
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 20 25565 arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25566 arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25567 arboristal.com.
...然后,按照变更日志中的提示执行 SRV 记录查找的 Minecraft 客户端将优先使用端口 25566 和 25567(各占 40% 的时间),而不是端口 25565(占 20% 的时间)。我们可以假设不找到并尊重这些 SRV 记录的 Minecraft 客户端将照常使用端口 25565。
但是,我认为使用负载平衡器(例如 Nginx)实际上会更“干净和专业”。 (我选择 Nginx 只是因为我以前使用过它。我并不是说它特别适合这项任务。出于某种原因,它甚至可能是一个糟糕的选择。)然后你没有弄乱您的 DNS,您可以使用相同的方法来负载平衡 任何 服务,而不仅仅是像 Minecraft 这样的那些碰巧完成了艰难的客户端工作来查找和尊重 SRV 记录的服务.要以 Nginx 的方式执行此操作,您可以在 arboristal.com 机器上运行 Nginx,并在 /etc/nginx/sites-enabled/arboristal.com 中使用类似以下内容:
upstream minecraft_servers {
ip_hash;
server 127.0.0.1:25566 weight=1;
server 127.0.0.1:25567 weight=1;
server 127.0.0.1:25568 weight=1;
}
server {
listen 25565;
proxy_pass minecraft_servers;
}
在这里,我们自己在服务器端控制负载平衡(通过 Nginx),因此我们不再需要担心表现不佳的客户端可能更喜欢端口 25565 而不是其他两个端口。事实上,现在所有客户都会与arboristal.com:25565 交谈!但是那个端口上的监听器不再是 Minecraft 服务器;它是 Nginx,秘密地将所有流量代理到同一台机器上的其他三个端口。
我们基于客户端 IP 地址 (ip_hash) 的哈希值进行负载平衡,因此如果客户端断开连接然后稍后重新连接,它很有可能会重新连接到它拥有的同一个 Minecraft 服务器前。 (我不知道这对 Minecraft 有多重要,也不知道启用 SRV 的客户端如何编程来处理这方面的问题。)
请注意,我们曾经在端口 25565 上运行 Minecraft 服务器;我已将其移至端口 25568,以便我们可以将端口 25565 用于负载平衡器。
Nginx 方法的一个可能缺点是它使 Nginx 成为系统中的瓶颈。如果 Nginx 出现故障,则所有三个服务器都将无法访问。如果系统的某些部分无法跟上单个端口 25565 上的流量,那么所有三台服务器都会变得不稳定。更不用说,Nginx 是您生态系统中的一个重要的新依赖项。也许您不想再引入另一个具有复杂配置语言和巨大攻击面的大型软件。我可以尊重这一点。
Nginx 方法的一个可能的优势是......它使 Nginx 成为您系统中的瓶颈!您可以通过 Nginx 应用全局策略,例如拒绝超过特定大小的数据包,或使用静态网页响应端口 80 上的 HTTP 连接。您还可以从 Internet 上屏蔽端口 25566、25567 和 25568,因为现在它们应该由 Nginx 通过环回接口与 only 交谈。这会在一定程度上减少您的攻击面。
Nginx 还可以更轻松地将新的 Minecraft 服务器添加到您的后端;现在您可以在配置中添加server 行和service nginx reload。使用旧的基于端口的方法,您必须向您的 DNS 提供商添加新的 SRV 记录(客户端可能需要最多 86400 秒才能注意到更改),然后也记得编辑您的防火墙(例如/etc/iptables.rules)以允许通过该新端口的外部流量。
Nginx 还让您在进行操作更改时不必考虑 DNS TTL。假设您决定将您的三个 Minecraft 服务器拆分到三个具有不同 IP 地址的不同物理机器上。使用 Nginx,您可以通过对 server 行的配置更改来完全做到这一点,并且您可以将这些新机器保留在防火墙内(仅通过私有接口连接到 Nginx),并且根据定义,更改将立即生效。然而,使用 SRV 记录,您必须将您的区域文件重写为类似这样的内容......
arboristal.com. 86400 IN CNAME mc1.arboristal.com.
mc1.arboristal.com. 86400 IN A <a new machine's IP address>
mc2.arboristal.com. 86400 IN A <a new machine's IP address>
mc3.arboristal.com. 86400 IN A <a new machine's IP address>
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 20 25565 mc1.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25565 mc2.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25565 mc3.arboristal.com.
...您必须将所有三台新机器都留在在您的防火墙之外,以便它们可以接收来自 Internet 的连接。 而且您必须等待 86400 秒才能让您的客户注意到更改,这可能会影响您的推出计划的复杂性。 而且如果您在arboristal.com 上运行任何其他服务(例如HTTP 服务器),现在您必须将它们移动到mc1.arboristal.com 机器上,因为我是如何使用CNAME 的。我这样做只是为了那些不尊重 SRV 记录并且仍会尝试连接到 arboristal.com:25565 的假设 Minecraft 客户的利益。
所以,我认为两种方式(SRV 记录和 Nginx 负载平衡)都是合理的,您的选择将取决于您的个人喜好。我将这些选项描述为:
- SRV 记录:“我只需要它工作。我不想要复杂性。而且我了解并信任我的 DNS 提供商。”
- Nginx:“我预见到
arboristal.com 会接管世界,或者至少有一天会搬到更大的机器上。我不害怕学习新工具。什么是区域文件?”