如何用App Engine的FastAPI调用Compute Engine虚拟机上的可执行程序?
问题背景
项目架构
- 前端:基于Svelte、SvelteKit构建,部署在App Engine上
- API:基于FastAPI构建,部署在App Engine上(*1:开发阶段前端与API服务器本地分端口部署,该模式能否迁移至App Engine?)
- 后端:专有代码/可执行程序存储在Compute Engine虚拟机中
核心流程
前端网页通过表单接收两个数字,点击按钮后以JSON格式(numbers.json)发送至API;API校验格式无误后,将numbers.json保存至虚拟机(*2:后续计划迁移至Cloud Storage),再运行自研可执行程序addition,读取numbers.json计算两数之和并生成sum.txt。
咨询问题
- App Engine应用托管API及API与Compute Engine通信的通用实践是什么?
- 上述示例中,如何通过FastAPI API向Compute Engine虚拟机发送JSON并运行可执行程序?
- 除了VPC Peering,还有哪些连接方案?
- Endpoints能否与Compute Engine通信?
解答
1. 本地分端口部署模式迁移至App Engine的可行性
完全可以迁移。App Engine支持两种适配方案:
- 多服务部署:将前端(SvelteKit)和FastAPI API分别作为独立的App Engine服务(比如命名为
frontend和api),各自拥有独立域名,本地跨端口调用直接替换为对应服务的域名即可。 - 单服务路由区分:利用SvelteKit的API路由功能,将FastAPI逻辑整合到SvelteKit项目中,通过不同路径区分前端页面和API接口,部署为单个App Engine服务。
2. App Engine托管API与Compute Engine通信的通用实践
网络层面
- VPC接入:通过App Engine的VPC连接器,将无服务器服务接入Compute Engine所在的VPC网络,让API可以直接访问虚拟机的内部IP,避免公网暴露。
- 身份权限控制:为App Engine服务账号授予Compute Engine相关权限(如
compute.instances.sendCommand用于执行远程命令、storage.objects.*用于后续Cloud Storage操作),基于Google Cloud IAM实现安全身份验证。 - 防火墙规则:禁用虚拟机的公网IP(或仅允许App Engine的IP段访问),通过VPC防火墙规则严格控制流量来源,避免未授权访问。
数据与流程层面
- 优先使用中间存储:如你后续计划的Cloud Storage,API接收JSON后先上传至Cloud Storage,再通知虚拟机读取处理,相比直接写入虚拟机文件系统,更可靠且易扩展。
- 异步任务队列:若计算耗时较长,建议使用Pub/Sub队列,API将任务消息发送到队列,虚拟机作为消费者监听队列并执行任务,避免API请求超时。
3. 示例中FastAPI向GCE发送JSON并运行可执行程序的实现方案
方案一:通过Google Cloud CLI执行远程命令
给App Engine服务账号授予compute.instances.sendCommand权限后,在FastAPI中调用gcloud命令完成操作:
from fastapi import FastAPI import subprocess import json app = FastAPI() @app.post("/calculate") async def calculate(numbers: dict): # 生成JSON内容 json_content = json.dumps(numbers) # 发送命令到GCE,写入文件并运行程序 cmd = [ "gcloud", "compute", "instances", "send-command", "INSTANCE_NAME", "--zone", "ZONE_NAME", "--command", f"""echo '{json_content}' > /path/to/numbers.json && /path/to/addition""" ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: return {"error": result.stderr} # 远程读取计算结果 read_cmd = [ "gcloud", "compute", "ssh", "INSTANCE_NAME", "--zone", "ZONE_NAME", "--command", "cat /path/to/sum.txt" ] sum_result = subprocess.run(read_cmd, capture_output=True, text=True) return {"sum": sum_result.stdout.strip()}
注:App Engine环境需预装Cloud SDK,或使用Google Cloud Python客户端库替代gcloud命令。
方案二:在GCE上部署轻量内部API
在虚拟机上部署一个简单的Flask/FastAPI服务,监听内部IP端口,App Engine通过VPC连接器直接调用:
- 虚拟机上的服务示例:
from flask import Flask, request import json import subprocess app = Flask(__name__) @app.post("/run-addition") def run_addition(): numbers = request.json with open("/path/to/numbers.json", "w") as f: json.dump(numbers, f) subprocess.run(["/path/to/addition"]) with open("/path/to/sum.txt", "r") as f: sum_val = f.read().strip() return {"sum": sum_val} if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
- App Engine的FastAPI调用该内部API:
import requests from fastapi import FastAPI app = FastAPI() GCE_INTERNAL_IP = "10.0.0.2" # 虚拟机内部IP @app.post("/calculate") async def calculate(numbers: dict): response = requests.post(f"http://{GCE_INTERNAL_IP}:5000/run-addition", json=numbers) response.raise_for_status() return response.json()
此方案更灵活,适合复杂操作,且降低了直接执行远程命令的安全风险。
4. 除VPC Peering外的连接方案
- VPC连接器(Serverless VPC Access):这是App Engine连接VPC最常用的方案,无需VPC Peering,直接将无服务器服务接入VPC网络,可直接访问虚拟机内部IP。
- 公网访问+身份验证:给虚拟机分配公网IP,在虚拟机服务中添加身份验证(如Identity-Aware Proxy或API密钥),App API通过公网调用,同时配置防火墙规则仅允许App Engine IP段访问。
- 中间层服务转发:将任务发送到Cloud Functions/Cloud Run,再由这些服务调用GCE的命令或内部API,实现更细粒度的权限控制和资源调度。
5. Endpoints能否与Compute Engine通信
可以。Google Cloud Endpoints可部署在App Engine、Cloud Run或GKE上,只要Endpoints所在服务能通过VPC连接器、公网等方式访问Compute Engine,就能实现通信。例如,将Endpoints配置在App Engine服务前端,流量先经过Endpoints转发到FastAPI API,再由API通过VPC连接器访问GCE,整个链路完全通畅。
内容的提问来源于stack exchange,提问作者fngarrett
相关产品推荐
相关产品推荐

