Cloud Run 中出现大量“Uncaught signal: 6”错误

Jer*_*ann 7 python-3.x docker google-cloud-platform google-cloud-run fastapi

我在 GCP 中部署了一个 Python (3.x) Web 服务。每次 Cloud Run 关闭实例时,尤其是在负载峰值之后,我都会收到许多类似这样的日志Uncaught signal: 6, pid=6, tid=6, fault_addr=0.,并且[CRITICAL] WORKER TIMEOUT (pid:6)它们始终是信号 6。

该服务正在使用 FastAPI 和 Gunicorn 通过此启动命令在 Docker 中运行

CMD gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8080 app.__main__:app
Run Code Online (Sandbox Code Playgroud)

该服务使用 Terraform 部署,具有 1 GB 内存、2 个 CPU,超时设置为 2 分钟

resource "google_cloud_run_service" <ressource-name> {
  name     = <name>
  location = <location>

  template {
    spec {
      service_account_name = <sa-email>
      timeout_seconds = 120
      containers {
        image = var.image
        env {
          name = "GCP_PROJECT"
          value = var.project
        }
        env {
          name = "BRANCH_NAME"
          value = var.branch
        }
        resources {
          limits = {
            cpu = "2000m"
            memory = "1Gi"
          }
        }
      }
    }
  }
  autogenerate_revision_name = true
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过调整 Cloud Run 中的资源和超时,使用 Gunicorn 的 --timeout 和 --preload 标志,因为人们在谷歌搜索问题时似乎总是推荐这样做,但都没有成功。我也不知道为什么工人们会超时。

小智 15

扩展正确的最佳答案,您正在使用GUnicorn,它是一个进程管理器,用于管理运行实际应用程序的Uvicorn进程。

当 Cloudrun 想要关闭实例时(可能是由于缺少请求),它会向进程 1 发送信号6。但是,GUnicorn 作为管理器占用此进程,并且不会将其传递给 Uvicorn 工作人员进行处理 - 因此您会收到未处理的信号 6

最简单的解决方案是直接运行 Uvicorn,而不是通过 GUnicorn(可能使用较小的实例),并允许通过 Cloudrun 处理缩放部分。

CMD ["uvicorn", "app.__main__:app", "--host", "0.0.0.0", "--port", "8080"]
Run Code Online (Sandbox Code Playgroud)


Joh*_*ley 8

除非您启用了“始终分配 CPU”,否则后台线程和进程可能会在所有 HTTP 请求返回后停止接收 CPU 时间。这意味着后台线程和进程可能会失败,连接可能会超时,等等。除了设置--cpu-no-throttle标志之外,我想不出使用 Cloud Run 运行后台工作程序有什么好处。可以终止不处理请求的 Cloud Run 实例。

信号 6 表示中止,终止进程。这可能意味着您的容器由于缺乏要处理的请求而被终止。

通过新的 CPU 分配控制在 Cloud Run 上运行更多工作负载

如果我的应用程序在请求处理之外执行后台工作怎么办?