前置情况
版本是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的?
mojang 程序员魅力时刻
测试换行1,直接回车
测试换行2,隔一行
测试换行3,回车后在上一行末尾添加3个空格
没错换行也一样(逃ps.你缺少的样式标签我后台帮你补上了