记录一次Minecraft JAVA服务器&客户端ping(motd)很慢、ipv6双栈的问题解决

前置情况

版本是1.20.4,使用0.57.0的frp,mc服务端和frp均为linux,架构均为x86

服务端为大陆境内,ipv4/v6双栈,frp为香港v4 only

在未作出修改之前,纯ipv4+端口的地址需要超过7秒的时间来响应motd

正文

对于时间的问题,首先需要排除的是不是物理延迟

tcping 47.76.x.x:35578
Ping tcp://47.76.x.x:35578(47.76.x.x:35578) - Connected - time=44.4059ms
Ping tcp://47.76.x.x:35578(47.76.x.x:35578) - Connected - time=43.7063ms
Ping tcp://47.76.x.x:35578(47.76.x.x:35578) - Connected - time=42.3623ms
Ping tcp://47.76.x.x:35578(47.76.x.x:35578) - Connected - time=46.9782ms

Ping statistics tcp://47.76.x.x:35578
4 probes sent.
4 successful, 0 failed.
Approximate trip times:
Minimum = 42.3623ms, Maximum = 46.9782ms, Average = 44.363175ms
mc服务端->frps 40ms
本地->frps 75ms

那么合计起来的往返时间,应该也不会超过300ms,单程时间也就一百多ms,更不该这么慢了

既然不是物理延迟,接下来需要考虑的是不是tcp粘包/通道拥堵的问题

这方面有两个可以入手,首先是关闭路由复用(某些小包多的情况下情况下可以减少延迟),还有就是bbr优化算法

完成这一步后,时间从七秒降到了5-6秒,基本可以忽略不计,说明瓶颈不在这里(也不奇怪,毕竟内部测试才不到三个人而已,mc发包优化烂的再怎么离谱也不至于到瓶颈)

接下来考虑的就是做跳板的frp了,某风同志一直吐槽说别家的香港也没这么慢,虽然说进去之后速度正常,但是motd的速度明显不正常

那么,尝试更新一下服务端的frp吧,实在不行换个映射工具试试?

换上去之后,速度还是,半斤八两,不过同时我也去别的地方问了一些别人(大概是来自ria的某位同志给了一条线索)

他建议我尝试fabric的fast ping ip,装上去之后确实速度明显快了不少,达到了100多ms握手的速度(和tcping结果一致),基本上秒出

从这个mod的介绍说明来看,也给出了真正的原因


引用自:https://modrinth.com/mod/fast-ip-ping

Yeet the laggy reversed DNS lookup for pure IP server addresses

Extracted from the yeetServerIpReversedDnsLookup option in TweakerMore Mod

What & Why & How

For servers whose addresses are represented solely by IP, e.g. 192.168.2.10:25565, disable reverse DNS lookups in the corresponding InetAddress object

Many non-loopback IPs lack associated domain names, which makes reverse lookups time-consuming

// java.net.InetAddress.getHostName(boolean)
String getHostName(boolean check) {
    if (holder().getHostName() == null) {  // It will be null if InetAddress.getByName() received a pure IP 
        holder().hostName = InetAddress.getHostFromNameService(this, check);  // <-- takes forever
    }
    return holder().getHostName();
}

This option sets the domain of those servers directly to their IP, bypassing the reverse DNS check

This results in a 1s ~ 5s reduction in time for servers with pure IP address. Affects the following environments:

  • Pinging the server in the server list screen
  • Connecting to the server

Environment

  • Client-side only
  • Fabric / Forge mod loader. No extra requirement is needed

解决

嗯,破案了,mc在纯ip地址试图寻找反向dns解析

然后多数情况下我们是没有配置的(而且除非自部署权威dns,否则大部分权威dns托管也不支持反向查找)

这么慢其实是mc一直在等dns返回结果超时的时间

所以说,配置个A记录和srv解析,问题解决了

后记:ipv6&双栈的疑难杂症

java为了保证向后兼容性,jvm有一个参数用于控制优先级

java.net.preferIPv6Addresses(默认值为false)mc的默认行为也受到此参数影响

对于双栈dns,当该值为false时,v4优先,否则v6优先(双栈了个寂寞属于是)

想要优先使用ipv6,只能更改jvm参数,或者使用纯v6地址(不论域名还是ip),并且v6的ip地址不会进行反向dns查询,因此速度很正常

后记的后记:ojng的加料

更新于 2024.4.26

引用自NS@miaoyun-link

删除客户端版本的json内

patchy:1.3.9 这个模块

客户端每次刷新服务器地址需要向mojang请求检测是否在黑名单内。

只能说,挺6的?

点赞
  1. GoodBoyboy说道:
    Google Chrome Windows 10/11
    服务端既然有ipv4/v6,为什么还要用香港的frp做跳板?
    1. 晓空说道:
      Google Chrome Windows 10/11
      服务端只有v6公网,所以需要跳板来提供v4给玩家用
  2. GoodBoyboy说道:
    Google Chrome Windows 10/11
    延迟6秒什么的太离谱了,我从华中跳香港再跳回来总共也就40ms :huaji3:
    1. 晓空说道:
      Google Chrome Windows 10/11
      所以解决之后速度就正常了嘛,只能说mc这真的是一坨屎山....
  3. HowieHz说道:
    Google Chrome Windows 10/11
    离谱,mc 在客户端对纯 ip 地址启用反向 dns 检查
    mojang 程序员魅力时刻
    1. HowieHz说道:
      Google Chrome Windows 10/11
      我换行怎么消失了2333
      测试换行1,直接回车

      测试换行2,隔一行
      测试换行3,回车后在上一行末尾添加3个空格
      1. 晓空说道:
        Google Chrome Windows 10/11
        :huaji2: 如果你打开留言板那个页面往下翻,你就会看到,markdown is unsupport,然后样式需要打html标签
        没错换行也一样(逃 :qy_chigua:
        ps.你缺少的样式标签我后台帮你补上了
        1. HowieHz说道:
          Google Chrome Windows 10/11
          2333 :地稽 2:
          1. 晓空说道:
            Google Chrome Windows 10/11
            :qy_witty:

发表回复

电子邮件地址不会被公开。必填项已用 * 标注