使用 HTTP/2 和 AWS ALB 在慢速网络上下载大文件失败

问题描述 投票:0回答:1

给出以下架构:

client <-> AWS NLB <-> AWS ALB <-> static file server

在慢速网络上使用 HTTP/2 时,客户端无法下载 12MB 文件,但在使用 HTTP/1.1 或带宽足够高时可以正常下载。无论文件是动态提供的(通过 Django)、作为来自 uwsgi 的静态文件还是作为来自 Nginx 的静态文件,都没有什么区别。

这是一个失败的示例(我使用 Socks 代理来限制带宽):

$ curl -x socks5://localhost:1080 https://example.com/file.pdf --output "file.pdf"

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
 79 12.6M   79 10.0M    0     0  61254      0  0:03:36  0:02:51  0:00:45 64422
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

但是,带有标志

--http1.1
的相同命令可以正常工作。

当我将下载限制为 512kbps 时,此操作会失败 - 它可以在 1024Kbps 下运行。我没有寻找最佳点,这并不重要。

备注:

  • 浏览器也会失败,这不是
    curl
    问题
  • curl
    -v
    一起使用不会提供任何附加信息。
  • 无论我尝试使用 Nginx 还是 uwsgi,它们都不会输出任何错误。就他们而言,他们已经完成了自己的工作。这是使用 uwsgi 时的示例输出 - Nginx 给出了类似的成功类型:
    [pid: 44|app: 0|req: 2603/9176] [ip] () {34 vars in 639 bytes} [Wed Oct 16 09:29:29 2024] GET /file.pdf => generated 13243923 bytes in 2425 msecs (HTTP/1.1 200) 8 headers in 314 bytes (103471 switches on core 0)
    
  • 同样,ALB 日志中也没有列出任何问题。它将请求记录为成功的请求,但字节数低于预期数量。

我想了解为什么 HTTP/2 和慢速网络会失败。我怀疑这与 ALB 有关。

aws-application-load-balancer
1个回答
0
投票

所以我发现了三件事可以解决这个问题:

  • 要求客户端使用HTTP/1.1
  • 将 ALB 设置为使用 HTTP/1.1
  • 将 ALB 的空闲超时时间增加到 120 秒

最后一点(这是我要寻求的解决方案)我只尝试作为最后的手段 - 因为相同的下载在 HTTP/1.1 上成功(相同的字节数,相同的网络条件)我没有预计超时或缓冲会成为问题。

然而,ALB 在 HTTP/2 中处理超时的方式似乎比在 HTTP/1.1 中更积极

如果我不得不冒险猜测:

  • uwsgi/nginx 将所有字节发送到 ALB,ALB 缓冲它们 [*]
  • ALB 和客户端之间的另一个设备(NLB、代理、路由器、防火墙等)缓冲部分数据 - 但不是全部数据
  • 客户端从该中间设备读取。当客户端读取了足够的数据,中间设备想要从 ALB 获取更多数据时,我们已经达到 60 秒超时,因此 ALB 关闭了连接
  • 这种情况发生在 HTTP/2 而不是 HTTP/1.1 上,可能是因为 ALB 在关闭 HTTP/2 流方面更加积极,因为同一个套接字由多个下载共享(完全猜测)。

我正在回答我自己的问题,但不会将其标记为已接受的答案,因为它们只是猜测。如果有人有一些明确的答案,我仍然想听听他们。

[*] 互联网并不清楚 ALB 是否会缓冲 - 有些人说它会缓冲,但由于它是近源且未在文档中指定,因此我们没有明确的答案

© www.soinside.com 2019 - 2024. All rights reserved.