我们有一个Reddit 上关于我的问题的讨论,但我也想在这里尝试一下。
我家里有一个对称的 300 Mbps 光纤连接,2021 年 9 月/10 月的某个时候,我开始看到奇怪的网络行为。在运行最新 macOS 的 MacBook 上,当转到一个已打开但一段时间不活动的选项卡时,Google Chrome 首次出现。如果该选项卡包含 GitHub、Reddit 或 StackOverflow,则刷新需要 10-30 秒。刷新后,它工作正常并快速加载,但在另一次不活动后,它再次发生。一次又一次。其他基于 Chromium 的浏览器也表现出同样的行为(测试了 Safari、Brave 和其他浏览器)。
调试 Chrome 后,发现一些 HTTP/2 请求出现停滞,并且 Chrome 需要等待 10 秒钟才能让每个请求响应。
t=13679 [st=10002] HTTP2_STREAM_ERROR
--> description = "Abandoned."
--> net_error = "ERR_HTTP2_PING_FAILED"
--> stream_id = 129
t=13679 [st=10002] HTTP_TRANSACTION_RESTART_AFTER_ERROR
--> net_error = -352 (ERR_HTTP2_PING_FAILED)
因此看起来某些 HTTP/2 连接已终止。Reddit 的一位用户发布了一个简单的 C keepalive 测试程序,该程序也复制了此问题。这是我的 fork,带有附加参数:https://gist.github.com/Najki/268cdf60ad6c9afcb4cb28c45f30d6e4
当这样运行时,它会从服务器读取 0 个字节(问题已复制)。这是 Google 的 IP 地址之一。第二个参数是端口。第三个参数是命令在从服务器读取响应之前将等待多长时间。
gcc keepalivetest.c -o /tmp/a.out && /tmp/a.out 172.217.16.46 80 80
其他观察结果:
- 仅当连接到我的 ISP(Inea)时才会发生这种情况。如果我从 iPhone 共享 LTE 连接或通过 VPN 连接,它就可以正常工作。
- 这只发生在 macOS 上。甚至在我的 macOS 上运行 Dockerized Linux 机器也能正常工作 → 这个看起来很奇怪。
- 我已多次联系我的 ISP,他们提出的唯一解决方法是支付额外费用来获得一个可以绕过他们的 NAT 或类似功能的公共 IP 地址。
这是怎么回事?是 macOS'a/Apple 的错吗?是我的 ISP 的错吗?我能做些什么吗?
答案1
您的 ISP 支持人员似乎说得对,问题是由他们的 NAT 服务器的不当行为引起的。他们显然不知道如何避免他们的服务器出现此问题,因此他们建议您使用静态公共 IP 完全避免 NAT。
分析:Chrome 会在向服务器发送请求数据之前/之后发送 PING 帧。你可以将此视为活动测试。这也类似于一个接一个地发送一连串 PING 请求。
如果此操作失败,则是因为浏览器和服务器之间的路径上的某个网络设备(可能是 NAT 服务器)决定丢弃有关您的连接的信息,而不向连接的两端发送 RST(重置连接)。换句话说,您的连接的 NAT 转换表(IP 转换)丢失了。
另一种可能性是,您的请求由 ISP 的两个 NAT 服务器提供服务,其中一个服务器不知道另一个服务器的存在,因此您的连接超时。
如果我的分析正确,那么您可以选择忍受问题,或者继续向 ISP 支持人员施压以解决他们的技术问题,或者更换 ISP,或者要求静态公共 IP。