2017-04-11 122 views
0

当我尝试连接到AWS RDS(MySQL)时,大多数时候我收到一个InterfaceError。当我编辑Lambda代码并重新运行时,它将在第一次正常工作,但是会出现相同的错误。AWS Lambda RDS MySQL数据库连接接口错误

我的代码:

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 

堆栈跟踪:

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, '') 

回答

3

Understanding Container Reuse in Lambda

它是关于Node编写的,但对Python来说也是一样准确。

在每次调用时,您的代码不会从顶部运行。有时它以handler开头。

为什么?速度更快。

你怎么知道什么时候会发生?除了每次重新部署函数外,您不会......除了每次重新部署函数外,当然,第一次调用时总是会得到一个新的容器,因为旧容器已被重新部署放弃。

如果你打算做处理程序之外的数据库连接,不叫conn.close(),因为在功能上的下一次调用,你可能发现您的容器仍然活着,并且处理函数时一个已经关闭的数据库句柄。

您必须编写Lambda函数,以便它们既不会在容器被重用时失败,也不会在容器未被重用时失败。

更简单的解决方案是在处理程序中打开数据库连接。更复杂但更优化的解决方案(就运行时而言)是永远不要关闭它,以便它可能被重用。

+0

谢谢@Michael。移动处理程序中的开放数据库连接,现在它工作正常。 – Jay