简体   繁体   English

AWS Lambda RDS MySQL数据库连接接口错误

[英]AWS Lambda RDS MySQL DB Connection InterfaceError

When I try to connect to AWS RDS (MySQL), most of the time I receive an InterfaceError . 当我尝试连接到AWS RDS(MySQL)时,大多数时候我会收到InterfaceError When I edit the Lambda code and re-run, it will work fine the first time, but then the same error occurs. 当我编辑Lambda代码并重新运行时,它将在第一次正常运行,但随后会发生相同的错误。

My code: 我的代码:

import sys
import logging
import pymysql
import json
import traceback
rds_host  = "*****.rds.amazonaws.com"
name = "*****"
password = "****"
db_name = "myDB"
logger = logging.getLogger()
logger.setLevel(logging.INFO)
try:
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
    sys.exit()
logger.info("SUCCESS: Connection to RDS mysql instance succeeded")
def handler(event, context):
    sub = event['sub']
    username = event['username']
    givenname = event['givenname']
    isAdmin = event['isAdmin']
    print (sub)
    print (username)
    print (givenname)
    print (isAdmin)
    data = {}

    cur = conn.cursor()
    try:
        cmd = "SELECT AuthState FROM UserInfo WHERE UserName=" + "\'" + username + "\'"
        rowCnt = cur.execute(cmd)
        print (cmd)
    except:
        print("ERROR: DB Query Execution failed.")
        traceback.print_exc()
        data['errorMessage'] = 'Internal server error'
        response = {}
        response['statusCode'] = 500
        response['body'] =  data
        return response
    if rowCnt <= 0:
        print (username)
        data['errorMessage'] = 'No User Name Found'
        response = {}
        response['statusCode'] = 400
        response['body'] =  data
        conn.close()
        return response
    for row in cur:
        print row[0]
        if int(row[0]) == 0:#NOT_AUTHORIZED
            ret = "NOT_AUTHORIZED"
        elif int(row[0]) == 1:#PENDING
             ret = "PENDING"
        elif int(row[0]) == 2:#AUTHORIZED
            ret = "AUTHORIZED"
        else:#BLOCKED
            ret = "BLOCKED"
    data['state'] = ret
    response = {}
    response['statusCode'] = 200
    response['body'] =  data
    conn.close()
    return response

The stacktrace: 堆栈跟踪:

Traceback (most recent call last):
  File "/var/task/app.py", line 37, in handler
  File "/var/task/pymysql/connections.py", line 851, in query
    self._execute_command(COMMAND.COM_QUERY, sql)
  File "/var/task/pymysql/connections.py", line 1067, in _execute_command
    raise err.InterfaceError("(0, '')")
InterfaceError: (0, '')

Read Understanding Container Reuse in Lambda . 阅读了解Lambda中的容器重用

It was written about Node but is just as accurate for Python. 它是关于Node编写的,但与Python一样准确。

Your code doesn't run from the top with each invocation. 您的代码并非每次调用都从头开始。 Sometimes it starts with the handler . 有时,它从handler开始。

Why? 为什么? It's faster. 它更快。

How do you know when this will happen? 您怎么知道什么时候会发生? You don't... except for each time you redeploy the function, of course, you'll always get a fresh container on the first invocation, because the old containers would have been abandoned by the redeploy. 您不需要...除了每次重新部署该函数外,您都会在第一次调用时总得到一个新的容器,因为旧的容器将被重新部署所放弃。

If you're going to do your DB connection outside the handler, don't call conn.close() , because on the next invocation of the function, you might find your container is still alive, and the handler is invoked with an already-closed database handle. 如果要在处理程序外部进行数据库连接,请不要调用conn.close() ,因为在下一次调用该函数时,您可能会发现您的容器仍处于活动状态,并且该处理程序已使用-关闭数据库句柄。

You have to write Lambda functions so that they neither fail if a container is reused, nor fail if a container is not reused. 您必须编写Lambda函数,以便它们既不会在容器被重用时失败,也不会在容器未被重用时失败。

The simpler solution is to open the DB connection inside the handler. 比较简单的解决方案是在处理程序中打开数据库连接。 The more complex but also more optimal solution (in terms of runtime) is to never close it, so that it can potentially be reused. 更加复杂但也是最佳的解决方案(就运行时而言)是永远不要关闭它,以便可以重用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM