连接到Cloud SQL时,Cloud Functions“连接被拒绝”

时间:2018-11-15 18:37:18

标签: python google-cloud-platform google-cloud-functions google-cloud-sql

我正在尝试与example provided by Google一起使用Python和MySQL实例将Cloud Functions脚本连接到Cloud SQL。

我在项目中创建了一个Cloud SQL实例,然后创建了一个Cloud Function,在其中我将链接中的整个脚本粘贴到了内联编辑器中。我将环境变量设置为等于连接到Cloud SQL所需的环境变量,但出现错误。

为了使这项工作有效,我是否缺少某些明显的东西?

  

错误:函数崩溃。细节:   (2003,“无法连接到'localhost'上的MySQL服务器([Errno 111]连接被拒绝)”)

     

跟踪(最近一次通话最近):文件“ /env/local/lib/python3.7/site-packages/pymysql/connections.py”,第582行,在连接** kwargs中)文件“ / opt / python3 .7 / lib / python3.7 / socket.py“,行727,在create_connection中引发err文件” /opt/python3.7/lib/python3.7/socket.py“,行716,在create_connection sock.connect( sa)ConnectionRefusedError:[Errno 111]连接被拒绝在处理上述异常期间,发生了另一个异常:追溯(最近一次调用为上):文件“ /user_code/main.py”,第49行,位于mysql_demo mysql_conn = pymysql.connect( ** mysql_config)连接返回Connection(* args,** kwargs)中第94行的文件“ /env/local/lib/python3.7/site-packages/pymysql/init.py” init self.connect()文件中的文件“ /env/local/lib/python3.7/site-packages/pymysql/connections.py”,第327行,文件“ / env / local / lib / python3.7 / site-packages / pymysql / connections.py”中的第629行,在连接中提高了pymysql.err.OperationalError:(2003年,“无法连接到MySQL服务器或n'本地主机'([Errno 111]连接被拒绝)“)在处理上述异常期间,发生了另一个异常:追溯(最近一次调用最近):文件” /env/local/lib/python3.7/site-packages/ pymysql / connections.py“,连接sock.connect(self.unix_socket)中的第570行,ConnectionRefusedError:[Errno 111]连接被拒绝在处理上述异常期间,发生了另一个异常:追溯(最近一次调用是最近的):文件” / env / local / lib / python3.7 / site-packages / google / cloud / functions_v1beta2 / worker.py“,第297行,位于run_http_function结果= _function_handler.invoke_user_function(flask.request)文件” / env / local / lib / python3 .7 / site-packages / google / cloud / functions_v1beta2 / worker.py“,第199行,在invoke_user_function中返回call_user_function(request_or_event)文件” /env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2 /worker.py“,第192行,在call_user_function中返回self._user_function(request_or_event)文件” /user_code/main.py“,第53行,在mysql_demo中,mysql _conn = pymysql.connect(** mysql_config)文件“ /env/local/lib/python3.7/site-packages/pymysql/init.py”,连接返回第94行,Connection(* args,** kwargs)文件“ /env/local/lib/python3.7/site-packages/pymysql/connections.py”,第327行,位于 init self.connect()文件中,“ / env / local / lib / python3.7 / site-packages / pymysql / connections.py“,第629行,在connect中,请举起pymysql.err.OperationalError:(2003年,“无法连接到'localhost'上的MySQL服务器( [Errno 111]拒绝连接)“)

2 个答案:

答案 0 :(得分:1)

非常重要的信息:

开始之前,您需要先执行GCP IAM,才能将Cloud SQL管理员角色添加到Cloud Function服务帐户中。服务帐户信息可以在云功能的常规选项卡中找到。完成此操作后,您应该一切顺利。如果没有,请尝试向您的云功能服务帐户添加更多角色,例如项目编辑器。

供代码参考,(仅要更改的部分)

# TODO(developer): specify SQL connection details  
CONNECTION_NAME = getenv(
'INSTANCE_CONNECTION_NAME',
'proj-chatbot-og:us-central1:your connection name')
# Please don't change the name on the left like MYSQL_USER
DB_USER = getenv('MYSQL_USER', 'your user name')
DB_PASSWORD = getenv('MYSQL_PASSWORD', 'your password')
DB_NAME = getenv('MYSQL_DATABASE', 'your sql database')


mysql_config = {
'user': DB_USER,
'password': DB_PASSWORD,
'db': DB_NAME,
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor,
'autocommit': True
}

完整文档可在此处https://cloud.google.com/functions/docs/sql

中找到

如果发现解决方案可以解决您的问题,请对解决方案进行投票。

答案 1 :(得分:0)

我遇到了同样的问题,在与Google反复交流之后,这终于为我解决了。

该示例显示以下try子句:

if not mysql_conn:
    try:
        mysql_conn = pymysql.connect(**mysql_config)
    except OperationalError:
        # If production settings fail, use local development ones
        mysql_config['unix_socket'] = f'/cloudsql/{CONNECTION_NAME}'
        mysql_conn = pymysql.connect(**mysql_config)

我将其更改为:

if not mysql_conn:
    mysql_config['unix_socket'] = f'/cloudsql/{CONNECTION_NAME}'
    mysql_conn = pymysql.connect(**mysql_config)

并使用(data, context)作为函数参数而不是(request)

这最终是我作为测试功能所要完成的:

from os import getenv

import pymysql
from pymysql.err import OperationalError

CONNECTION_NAME = getenv(
  'INSTANCE_CONNECTION_NAME',
  'connection_name')
DB_USER = getenv('MYSQL_USER', 'username')
DB_PASSWORD = getenv('MYSQL_PASSWORD', 'password')
DB_NAME = getenv('MYSQL_DATABASE', 'database')

mysql_config = {
  'user': DB_USER,
  'password': DB_PASSWORD,
  'db': DB_NAME,
  'charset': 'utf8mb4',
  'cursorclass': pymysql.cursors.DictCursor,
  'autocommit': True
}

if getenv('NODE_ENV', '') == 'production':
    mysql_config['unix_socket'] = f'/cloudsql/{CONNECTION_NAME}'

# Create SQL connection globally to enable reuse
# PyMySQL does not include support for connection pooling
mysql_conn = None


def __get_cursor():
    """
    Helper function to get a cursor
    PyMySQL does NOT automatically reconnect,
    so we must reconnect explicitly using ping()
    """
    try:
        return mysql_conn.cursor()
    except OperationalError:
        mysql_conn.ping(reconnect=True)
        return mysql_conn.cursor()


def mysql_demo(data, context):
    global mysql_conn

    # Initialize connections lazily, in case SQL access isn't needed for this
    # GCF instance. Doing so minimizes the number of active SQL connections,
    # which helps keep your GCF instances under SQL connection limits.
    if not mysql_conn:
        mysql_conn = pymysql.connect(**mysql_config)

    # Remember to close SQL resources declared while running this function.
    # Keep any declared in global scope (e.g. mysql_conn) for later reuse.
    with __get_cursor() as cursor:
        cursor.execute('SELECT NOW() as now')
        results = cursor.fetchone()
        return str(results['now'])