Cloud Function 无法连接到 Cloud SQL,并出现“上游请求超时”

问题描述 投票:0回答:1

正如标题所示,我的云功能正在记录“已完成状态:‘错误’”,没有其他日志。我正在使用带有 Python 3.10 的第一代 Cloud Functions。

下面是我基于此笔记本编写的代码:https://colab.research.google.com/github/GoogleCloudPlatform/cloud-sql-python-connector/blob/main/samples/notebooks/postgres_python_connector.ipynb #scrollTo=0CnzkOianTNN

import sqlalchemy
from google.cloud import secretmanager
from google.cloud.sql.connector import Connector, IPTypes

PROJECT_ID = "REDACTED"
connector = Connector()


def getconn():
    conn = connector.connect(
        "REDACTED",
        "pg8000",
        user="REDACTED",
        password="REDACTED",
        db="REDACTED",
        ip_type=IPTypes.PUBLIC,
    )
    return conn


pool = sqlalchemy.create_engine(
    "postgresql+pg8000://",
    creator=getconn,
)


def main(request):
    try:
        max_version = None
        # connect to connection pool
        with pool.connect() as db_conn:
            row = db_conn.execute(
                sqlalchemy.text(
                    "select coalesce(max(version), 0) as max_version from pricings"
                )
            ).fetchone()

            # show results
            max_version = row[0]
        return {"max_version": max_version}
    except Exception as e:
        print(e)
        return "error"

我看到的唯一日志是“函数执行已开始”和“函数执行花费了 x 毫秒,已完成,但状态错误”。甚至没有打印异常。

这个功能在本地运行正常,但是一旦部署就不行了。

编辑: 一旦我将连接方法更改为 Unix Socket 而不是 cloud sql python 连接器,它现在可以在 GCP 上运行。但显然不是本地的。

google-cloud-platform google-cloud-functions google-cloud-sql
1个回答
0
投票

这是由于 Cloud Functions 的性质以及 Cloud SQL Python 连接器运行后台任务。

事实证明,运行后台任务的全局变量在 Cloud Function 请求上下文之外运行时可能会导致问题(因为 Cloud Functions 仅在发出第一个请求时分配计算)。因此,Cloud Functions 建议延迟初始化这种类型的全局变量,以便在请求上下文中初始化该变量。

import sqlalchemy
from google.cloud.sql.connector import Connector, IPTypes
import pg8000

def connect_to_instance() -> sqlalchemy.engine.base.Engine:
    connector = Connector()

    def getconn() -> pg8000.dbapi.Connection:
        return connector.connect(
            "...", # the PostgreSQL's instance connection name here
            "pg8000",
            user     = "xyz",
            password = 'supersecret',
            db       = "db_name",
            ip_type  = IPTypes.PUBLIC
        )
    
    return sqlalchemy.create_engine(
        "postgresql+pg8000://",
        creator      = getconn,
        pool_size    = 5,
        max_overflow = 2,
        pool_timeout = 30,
        pool_recycle = 1800
    )

# lazy initialization of global db
db = None

def hello_http(request):
    # lazy init within request context
    global db
    if not db:
        db = connect_to_instance()
    with db.connect() as db_conn:
        # ... perform queries

正如您所提到的,这也作为 https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/issues/830

的一部分提到
© www.soinside.com 2019 - 2024. All rights reserved.