Cloud-Run进程失败,返回500状态码,并出现membarrier gvisor错误。

5

背景

该服务是一个简单的Go程序,将Cloud Storage中的文件传输到浏览器。

在我的Macbook上一切正常,但对于某些请求,例如大型mp4文件,在Cloud-Run(托管)上失败。

问题

日志只显示500状态,浏览器也是如此。但是我的服务除了开始复制文件之外没有记录任何其他内容。没有IO错误或任何其他错误。

这条消息在500状态之前显示4秒:

Container Sandbox Limitation: Unsupported syscall membarrier(0x10,0x0,0x0,0x8,0x775dce0b030,0x775dce0b000). Please, refer to https://gvisor.dev/c/linux/amd64/membarrier for more information.

我无法在本地重现此问题。使用相同的配置和GCP存储桶在本地运行良好。

该服务在Cloud-Run上使用较小的文件(例如图像)正常工作。只不过我尝试过的视频不行。

我已经尝试过

  • 记录所有内容直到io.Copy。 没有错误,但在调用io.Copy后挂起。
  • 增加容器的内存。现在正在运行1G。与512M没有任何区别。
  • 使用相同的配置和凭据在本地的Docker容器中运行。 没有问题。
  • 在Twitter上寻求GCP的帮助

更新2019-08-16

我创建了一个非常简单的服务,将“ A”打印到http responsewriter。它在本地也完美工作,但在Cloud-Run上返回500(对于较大的尺寸)。 1MB OK,5MB OK,50MB失败,100MB失败等。当此服务运行时,没有membarrier消息。

代码在此处可用:https://github.com/andrioid/reproduce-cloud-run-bug

也在问题跟踪器上报告了此问题:https://issuetracker.google.com/issues/139511257

更新2:可能的原因

似乎响应大小的硬限制为32MB。

https://cloud.google.com/run/quotas

非常失望,无法增加此限制,并且错误没有提及此限制,日志文件也没有提及。


在 Docker 容器中本地运行,使用相同的配置和凭据。没有问题。 你是否在 gVisor 中运行它?因为在 linux/amd64 gvisor 上不支持 syscall membarrier。 - Vitaly Migunov
我还没有尝试过使用gvisor。你知道如何在Mac上安装它吗?我甚至不确定membarrier是否引起了这个问题。 - Andrioid
1
我曾经遇到过与第三方二进制文件类似的问题。请提交一个带有代码示例的问题以获得支持。这将有助于您并调查该问题。您可以尝试使用Appengine Flex(它对我有效),但它不能缩放到0。 - guillaume blaquiere
有人发现了相同的错误并且能够除了配额限制之外调试其他东西吗?我没有处理大文件,也无法调试为什么会调用该系统调用。 - BBerastegui
3个回答

0

你知道它没有被实现的后果吗?Stackdriver 报告它为 DEBUG。有人知道我的 Go 代码中可能是什么在调用这个系统调用吗?我唯一的依赖是 gocloud.dev。 - Andrioid

0
请注意,您始终可以在Google Cloud官方问题跟踪器上报问题。https://cloud.google.com/support/docs/issue-trackers
在大多数情况下,gVisor中未实现的系统调用不会导致应用程序崩溃(因为大多数语言使用回退方式,使用更基本或遗留的系统调用)。
我建议跟踪链接中提到的问题,并回复说您在Cloud Run上遇到了这个问题,并最好提供一个触发此情况的小程序。这种问题通常会在几周内得到解决,具体取决于发布周期。
似乎Go在其高级代码中没有执行此系统调用[1],但可能是由于以汇编语言编写的低级Go运行时代码导致了这种情况。

0

HTTP请求和响应的32 MB限制不是Cloud Run的限制,而是位于Cloud Run Managed前面的GFE(全球前端服务)的限制。

注意:本答案不包括Cloud Run on Kubernetes,仅涉及Cloud Run Managed。

GFE是一个反向代理,用于终止TCP连接。 GFE为Cloud Run提供了其他功能,例如公共DNS名称的公共IP托管、拒绝服务(DoS)保护和TLS终止。

GFE用于许多Google服务,因此我怀疑这种限制在不久的将来会改变。


这就解释了为什么500错误来自于一个叫做“Google Frontend”的东西。感谢提供信息。我想我可以通过重定向到存储链接而不是直接传输来解决这个问题。任何事情都不要让我自己操心服务器 :-) - Andrioid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接