(我做这些东西已经有一段时间了。请不要盲目地假设下面的所有细节都是正确的。但我希望我不会错得太尴尬。:))
正如前面的答案所述,Minecraft 客户端(从 1.3.1 开始)支持使用服务名称和协议名称查找SRV 记录,这意味着如果您的区域文件看起来像这样......_minecraft
_tcp
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 通过环回接口与之交谈。这会在一定程度上减少您的攻击面。
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
几秒钟才能让您的客户注意到更改,这可能会影响您的推出计划的复杂性。如果您在 上运行任何其他服务(例如 HTTP 服务器)arboristal.com
,现在您必须将它们移动到mc1.arboristal.com
机器上,因为我是如何使用 CNAME 的。我这样做只是为了那些不尊重 SRV 记录并且仍将尝试连接到arboristal.com:25565
.
所以,我认为两种方式(SRV 记录和 Nginx 负载平衡)都是合理的,您的选择将取决于您的个人喜好。我将这些选项讽刺为:
- SRV 记录:“我只需要它工作。我不想要复杂性。而且我了解并信任我的 DNS 提供商。”
- Nginx:“我预见到
arboristal.com
会接管世界,或者至少有一天会搬到更大的机器上。我不害怕学习新工具。什么是区域文件?”