[英]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.