Облачные функции «Отказано в соединении» при подключении к Cloud SQL - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь следовать примеру , предоставленному Google , для подключения скрипта Cloud Functions к Cloud SQL с Python и экземпляром MySQL.

Я создал экземпляр Cloud SQL в проекте, а затем создал функцию Cloud, в которую я вставил весь скрипт из ссылки в встроенный редактор. Я установил переменные окружения равными тем, какими они должны быть для подключения к Cloud SQL, но я получаю ошибку.

Есть ли что-то очевидное, чего мне не хватает, чтобы заставить эту работу?

Ошибка: сбой функции. Подробности: (2003, «Не удается подключиться к серверу MySQL на« localhost »([Errno 111] Соединение отклонено)»)

Traceback (последний вызов был последним): Файл "/env/local/lib/python3.7/site-packages/pymysql/connections.py", строка 582, в файле connect ** 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) Файл "/env/local/lib/python3.7/site-packages/pymysql/init.py", строка 94, в файле Connect return 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 connect exc exc pymysql.err.OperationalError: (2003," Не удается подключиться к серверу MySQL в 'loca " lhost '([Errno 111] Соединение отклонено) ") Во время обработки вышеупомянутого исключения произошло другое исключение: обратная связь (последний вызов был последним): файл" /env/local/lib/python3.7/site-packages/pymysql/ connections.py ", строка 570, в connect sock.connect (self.unix_socket) ConnectionRefusedError: [Errno 111] Соединение отклонено Во время обработки вышеуказанного исключения произошло другое исключение: обратная связь (последний вызов был последним): файл" / env / local / lib / python3.7 / site-packages / google / cloud / functions_v1beta2 / worker.py ", строка 297, в файле run_http_function result = _function_handler.invoke_user_function (flask.request) File" /env/local/lib/python3.7 /site-packages/google/cloud/functions_v1beta2/worker.py ", строка 199, в invoke_user_function return call_user_function (request_or_event) Файл" /env/local/lib/python3.7/site-packages/google/cloud/functions_verbeta2 .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, в Connect возвращает соединение (* 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 connect exc exc pymysql.err.OperationalError: (2003," Невозможно подключиться к серверу MySQL на 'localhost' ([Errno 111] Соединение отказано) ")

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Очень важная информация:

Прежде чем приступить к работе, необходимо перейти к GAM IAM, чтобы добавить роль администратора облачного SQL в учетную запись службы облачных функций.Информацию об учетной записи службы можно найти на общей вкладке облачной функции.После того, как вы выполните это действие, вы должны быть готовы.Если нет, попробуйте добавить дополнительные роли в свою учетную запись службы облачных функций, например, редактор проектов.

Для справки по коду (только часть для изменения)

# 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

Пожалуйста, проголосуйте за решение, если вы нашли решение, которое решило вашу проблему.

0 голосов
/ 30 ноября 2018

У меня возникла та же проблема, и после долгих поисков в 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'])
...