解决GCP Cloud Function(Gen2)部署时端口监听失败问题
解决GCP Cloud Function Gen2部署时Cloud Run端口监听错误
你的代码核心问题是直接在模块级别启动了Pub/Sub订阅监听循环,这和Cloud Function Gen2(基于Cloud Run)的运行模式冲突。Cloud Run要求容器启动后监听指定端口,由Functions Framework处理触发事件;而你的代码在启动时直接进入了订阅阻塞循环,导致Functions Framework无法启动HTTP服务监听端口,从而触发错误。
1. 重构Main.py代码
移除模块级别的订阅逻辑,让winodds作为Cloud Function的Pub/Sub触发函数,由GCP负责管理Pub/Sub订阅和消息推送,而非自行启动监听:
from google.cloud import firestore import requests import json import google.auth import base64 credentials, project = google.auth.default() # API INFO Base_url = 'https://xxxxxxxx.net/v1/feeds/sportsbookv2' Sport_id = 'xxxxxxxx' AppID = 'xxxxxxxx' AppKey = 'xxxxxxxx' Country = 'en_AU' Site = 'www.xxxxxxxx.com' db = firestore.Client(project='xxxxxxxx') def winodds(event, context): # 解析Pub/Sub消息(数据为base64编码) try: message_data = base64.b64decode(event['data']).decode('utf-8') events = json.loads(message_data) event_ids = events['event_ids'] except Exception as e: print(f"解析消息失败: {e}") return url = f"{Base_url}/betoffer/event/{','.join(map(str, event_ids))}.json?app_id={AppID}&app_key={AppKey}&local={Country}&site={Site}" print(url) windata = requests.get(url).text windata = json.loads(windata) for odds_data in windata['betOffers']: if odds_data['betOfferType']['name'] == 'Head to Head' and 'MAIN' in odds_data['tags']: event_id = odds_data['eventId'] home_team = odds_data['outcomes'][0]['participant'] home_team_win_odds = odds_data['outcomes'][0]['odds'] away_team = odds_data['outcomes'][1]['participant'] away_team_win_odds = odds_data['outcomes'][1]['odds'] print(f'{event_id} {home_team} {home_team_win_odds} {away_team} {away_team_win_odds}') # 写入Firestore doc_ref = db.collection(u'xxxxxxxx').document(u'basketball_nba').collection(u'win_odds').document(f'{event_id}') doc_ref.set({ u'event_id': event_id, u'home_team': home_team, u'home_team_win_odds': home_team_win_odds, u'away_team': away_team, u'away_team_win_odds': away_team_win_odds, u'timestamp': firestore.SERVER_TIMESTAMP, }) # 本地测试用(可选) if __name__ == "__main__": test_event = { 'data': base64.b64encode(json.dumps({"event_ids": [12345]}).encode('utf-8')).decode('utf-8') } winodds(test_event, None)
修改点说明:
- 移除所有
pubsub_v1.SubscriberClient相关的订阅、监听代码,Cloud Function会自动处理Pub/Sub消息推送 - 调整
winodds函数参数为Cloud Function Pub/Sub触发要求的event和context,添加消息base64解码逻辑(Pub/Sub消息默认编码) - 移除模块级别的阻塞循环,让Functions Framework能够正常启动HTTP服务监听端口
2. 调整Dockerfile(保留核心配置即可)
你的Dockerfile配置基本正确,可移除调试参数并确保端口配置正确:
# Use the official Python image. FROM python:3.10 ENV APP_HOME /app WORKDIR $APP_HOME COPY . . ENV GOOGLE_APPLICATION_CREDENTIALS /app/xxxxx-key.json ENV PORT 8080 # 安装依赖 RUN pip install functions-framework RUN pip install -r requirements.txt # 启动服务 CMD exec functions-framework --target=winodds --port=$PORT
3. 部署注意事项
- 部署Cloud Function Gen2时,选择Pub/Sub触发,指定对应的主题(GCP会自动创建订阅,无需代码处理)
- 确保服务账号拥有Pub/Sub订阅权限、Firestore写入权限
内容的提问来源于stack exchange,提问作者DrewS
相关产品推荐
相关产品推荐

