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

如何配置多URL指向同一Flex App Engine及多客户端Cloud SQL映射

Hey Johnny, let's break down your two questions step by step—here's how to tackle both scenarios:

1. 设置多个URL指向同一个Flex App Engine

让多个子域名(比如client1.app.mydomain.com)指向你的Flex应用,通过Google Cloud的自定义域名映射就能轻松实现:

  • 验证根域名:打开Google Cloud控制台,进入你的App Engine项目,找到「自定义域名」页面。添加你的根域名(比如mydomain.com),按照提示完成域名所有权验证——通常需要在域名服务商的DNS后台添加一条TXT或CNAME记录。
  • 映射子域名到应用:根域名验证通过后,添加你需要的所有子域名(比如client1.app.mydomain.com、client2.app.mydomain.com)。Google会为每个子域名提供对应的DNS记录(非根域名用CNAME, apex域名用A/AAAA记录),把这些记录添加到你的域名服务商DNS设置里即可。
  • 开启HTTPS:App Engine会自动为自定义域名免费配置Let's Encrypt证书,记得为所有子域名开启HTTPS,保障客户端访问的安全性。
2. 多客户端通过各自Cloud SQL实例访问同一代码库

要让每个客户端连接到专属的Cloud SQL实例同时共用一套代码,你需要根据请求的子域名动态路由数据库连接。具体步骤如下:

步骤1:从子域名识别客户端

首先,你的Python应用需要从请求的子域名中提取客户端标识。这里给你两个常用框架的示例:

Flask示例

from flask import Flask, request, g

app = Flask(__name__)

@app.before_request
def set_client_context():
    # 提取客户端前缀(比如从"client1.app.mydomain.com"中拿到"client1")
    host_parts = request.host.split('.')
    g.client_id = host_parts[0] if len(host_parts) > 2 else None

Django示例

创建一个自定义中间件,把客户端ID绑定到请求对象上:

# your_app/middleware.py
class ClientIdentificationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        host_parts = request.get_host().split('.')
        request.client_id = host_parts[0] if len(host_parts) > 2 else None
        response = self.get_response(request)
        return response

然后在settings.py中注册这个中间件:

MIDDLEWARE = [
    # ... 其他默认中间件
    'your_app.middleware.ClientIdentificationMiddleware',
]

步骤2:动态连接对应的Cloud SQL实例

接下来,用识别到的客户端ID获取对应的Cloud SQL实例信息并建立连接,这里提供两种安全的实现方式:

方式1:用环境变量存储实例映射

在app.yaml中存储客户端ID到Cloud SQL实例连接名的映射:

env_variables:
  CLIENT_DB_MAP: '{"client1": "你的项目ID:地域:client1-sql", "client2": "你的项目ID:地域:client2-sql"}'
  DB_USER: "数据库用户名"
  DB_NAME: "数据库名"

然后在代码中动态加载连接(以PostgreSQL为例):

import json
import os
import psycopg2

def get_db_connection(client_id):
    # 加载客户端与实例的映射关系
    db_map = json.loads(os.environ.get('CLIENT_DB_MAP', '{}'))
    instance_name = db_map.get(client_id)
    if not instance_name:
        raise ValueError(f"未为客户端 {client_id} 配置数据库")
    
    # 在Flex环境中连接Cloud SQL
    conn = psycopg2.connect(
        user=os.environ['DB_USER'],
        password=os.environ['DB_PASSWORD'],  # 生产环境建议用Secret Manager存储密码!
        dbname=os.environ['DB_NAME'],
        host=f'/cloudsql/{instance_name}'
    )
    return conn

方式2:用Secret Manager安全存储凭证

为了更高的安全性,把每个客户端的数据库凭证存在Google Cloud Secret Manager中:

  1. 为每个客户端创建一个Secret(比如client1-db-creds),内容为JSON格式:{"instance_name": "你的项目ID:地域:client1-sql", "user": "数据库用户名", "password": "数据库密码", "db_name": "数据库名"}
  2. 给你的App Engine服务账号授予roles/secretmanager.secretAccessor权限
  3. 在代码中动态获取Secret并建立连接:
import json
import os
from google.cloud import secretmanager
import psycopg2

def get_client_db_creds(client_id):
    client = secretmanager.SecretManagerServiceClient()
    secret_path = f"projects/{os.environ['GOOGLE_CLOUD_PROJECT']}/secrets/{client_id}-db-creds/versions/latest"
    response = client.access_secret_version(request={"name": secret_path})
    return json.loads(response.payload.data.decode('utf-8'))

def get_db_connection(client_id):
    creds = get_client_db_creds(client_id)
    conn = psycopg2.connect(
        user=creds['user'],
        password=creds['password'],
        dbname=creds['db_name'],
        host=f'/cloudsql/{creds["instance_name"]}'
    )
    return conn

步骤3:配置Cloud SQL访问权限

  • 给每个Cloud SQL实例的IAM权限列表中,添加你的App Engine服务账号,并授予roles/cloudsql.client权限
  • 如果用公网IP,需要把App Engine的出口IP段添加到Cloud SQL实例的授权网络中;如果用私有IP,需要配置App Flex环境与Cloud SQL实例所在VPC的对等连接

内容的提问来源于stack exchange,提问作者Mapperkids Lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:44:32