You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Cloud Run非服务器进程无法进入就绪状态问题咨询

解决Cloud Run中非服务器进程的就绪状态问题

问题背景

在Google Cloud Run中运行Python WebSocket客户端脚本,已成功连接第三方WebSocket服务器(提供了URI和API密钥)并正常传输数据,但Cloud Run始终无法将容器识别为就绪状态。排查后确认:Cloud Run要求进程必须监听暴露的端口,而客户端脚本本身不具备监听端口的能力,这是导致就绪检测失败的核心原因。

原客户端脚本

import asyncio
from websockets.client import connect

async def hello():
    headers = {
        "Authorization": "Bearer " + "API_KEY",
        "Sec-WebSocket-Version": "13",
        "Connection": "Upgrade",
        "Upgrade": "websocket",
        "Host": "logstream.3rdparty.com:443"
    }
    
    async with connect(uri="wss://logstream.3rdparty.com:443/v1/stream?cid=mycompany_hosted&type=message", extra_headers=headers) as websocket:
        while True:
            message = await websocket.recv()
            print(f"Received: {message[:20]}")

asyncio.run(hello())

原Dockerfile

FROM python:3.10

ENV ENV=dev \
TOPIC_PROJECT_ID=project_id \
TOPIC_NAME=dev-topic_name \
API_KEY=API_KEY \
 \
PORT=8765 \
HOSTNAME=0.0.0.0

EXPOSE 8080

COPY . /workdir

WORKDIR /workdir

RUN pip install -r requirements.txt

ENTRYPOINT ["python", "main.py"]

解决方案

Cloud Run的就绪检测默认会向容器的8080端口发送HTTP请求,只要进程能监听该端口并响应请求,就会被标记为就绪。我们可以通过添加一个轻量的HTTP服务来满足这个要求,同时不影响WebSocket客户端的正常运行。

1. 修改客户端脚本,添加HTTP监听服务

调整脚本,使用asyncio同时运行两个任务:WebSocket客户端逻辑和一个简易HTTP服务器。示例代码如下:

import asyncio
import os
from websockets.client import connect
from http.server import BaseHTTPRequestHandler, HTTPServer

# 简易HTTP请求处理器,仅响应200状态
class HealthCheckHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        self.wfile.write(b'Ready')

    # 关闭日志输出,避免干扰WebSocket日志
    def log_message(self, format, *args):
        pass

async def run_http_server(port):
    server = HTTPServer(('0.0.0.0', port), HealthCheckHandler)
    # 用asyncio包装同步的HTTP服务器
    await asyncio.get_event_loop().run_in_executor(None, server.serve_forever)

async def websocket_client():
    headers = {
        "Authorization": "Bearer " + os.getenv('API_KEY'),
        "Sec-WebSocket-Version": "13",
        "Connection": "Upgrade",
        "Upgrade": "websocket",
        "Host": "logstream.3rdparty.com:443"
    }
    
    async with connect(uri="wss://logstream.3rdparty.com:443/v1/stream?cid=mycompany_hosted&type=message", extra_headers=headers) as websocket:
        while True:
            message = await websocket.recv()
            print(f"Received: {message[:20]}")

async def main():
    # 获取Cloud Run指定的端口,默认8080
    port = int(os.getenv('PORT', 8080))
    # 同时运行HTTP服务器和WebSocket客户端
    await asyncio.gather(
        run_http_server(port),
        websocket_client()
    )

if __name__ == "__main__":
    asyncio.run(main())

2. 调整Dockerfile配置

清理无用环境变量,确保端口配置与脚本一致:

FROM python:3.10

ENV API_KEY=API_KEY \
PORT=8080 \
HOSTNAME=0.0.0.0

EXPOSE 8080

COPY . /workdir

WORKDIR /workdir

RUN pip install -r requirements.txt

ENTRYPOINT ["python", "main.py"]

关键说明

  • 新增的HTTP服务器仅用于响应Cloud Run的就绪检测请求,不会消耗过多资源
  • 确保脚本监听的端口与Dockerfile中EXPOSE的端口、环境变量PORT一致,Cloud Run默认使用8080端口
  • 若需要自定义就绪检测路径,可以修改HealthCheckHandler的do_GET方法,处理特定路径的请求

内容的提问来源于stack exchange,提问作者Rudolph Sargenti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:28:13