GKE 流式传输大文件下载失败并出现部分响应
Posted
技术标签:
【中文标题】GKE 流式传输大文件下载失败并出现部分响应【英文标题】:GKE streaming large file download fails with partial response 【发布时间】:2020-03-09 21:42:47 【问题描述】:我有一个托管在 GKE 上的应用程序,在许多任务中,它向客户端提供一个 zip 文件。这些 zip 文件是通过谷歌云存储上的许多单独文件动态构建的。
我面临的问题是,当这些 zip 变得特别大时,连接会随机失败(介于 1.4GB 到 2.5GB 之间)。似乎也没有任何时间模式 - 它可能发生在 2-8 分钟之间。
AFAIK,负载平衡器和我的应用程序之间的连接断开了。是否已知 GKE 入口(负载平衡器)会关闭长/大连接?
GKE 设置:
HTTP(S) 负载平衡器入口 NodePort 后端服务 部署(我的应用)更多细节/调试步骤:
我无法在本地复制它(没有 kubernetes)。 负载平衡器记录statusDetails: "backend_connection_closed_after_partial_response_sent"
,而响应具有 200 状态代码。对此的谷歌没有提供任何帮助。
直接访问pod并使用k8s port-forward下载成功
我的应用记录了请求已被取消(由请求者)
我可以验证没有文件损坏(可以直接从存储中下载所有文件)
【问题讨论】:
您是否在 nginx 上运行您的应用程序并使用 websocket procol 下载文件? 【参考方案1】:我相信您的“backend_connection_closed_after_partial_response_sent”问题是由后端过早终止 websocket 连接引起的。您可以在 websocket proxying in nginx 上查看文档 - 它解释了此过程的性质。简而言之 - 默认情况下 WebSocket 连接会在 10 分钟后终止。
为什么直接从 pod 下载文件会起作用?因为您绕过了负载平衡器,并且 websocket 连接保持正常活动。当您代理 websocket 时,事情开始发生,因为 WebSocket 依赖于未代理的逐跳标头。
类似case was discussed here。它是通过从后端向客户端发送 ping 帧来解决的。
在我看来,你最好的办法就是这样做。当 websocket 被代理时,我发现很多类似问题的案例,其中大多数建议使用 ping,因为它会重置连接计时器并使其保持活动状态。
这里有更多关于pinging the client using WebSocket和timeouts的信息
我在 Google 工作,这就是我可以帮助您的能力 - 如果这不能解决您的问题,您必须联系 GCP 支持。
【讨论】:
我有这里提到的类似问题***.com/questions/60464596/…,我没有让你ping东西,只是简单地ping我的客户还是我需要其他东西?以上是关于GKE 流式传输大文件下载失败并出现部分响应的主要内容,如果未能解决你的问题,请参考以下文章
Groovy Grails,如何在控制器的响应中流式传输或缓冲大文件?