2017-04-11 163 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