2017-04-11 6 views
0

Wenn ich versuche, eine Verbindung zu AWS RDS (MySQL), die meiste Zeit bekomme ich eine InterfaceError. Wenn ich den Lambda-Code bearbeite und neu starte, funktioniert es beim ersten Mal einwandfrei, aber dann tritt derselbe Fehler auf.AWS Lambda RDS MySQL DB Verbindung InterfaceError

Mein 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 

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

Antwort

3

lesen Understanding Container Reuse in Lambda.

Es wurde über Node geschrieben, ist aber genauso genau für Python.

Ihr Code wird bei jedem Aufruf nicht von oben ausgeführt. Manchmal beginnt es mit der handler.

Warum? Es ist schneller.

Woher wissen Sie, wann das passiert? Sie werden nicht ... außer bei jeder erneuten Bereitstellung der Funktion erhalten Sie beim ersten Aufruf immer einen neuen Container, weil die alten Container durch die erneute Bereitstellung aufgegeben worden wären.

Wenn Sie vorhaben, Ihre DB-Verbindung außerhalb des Handlers tun, conn.close() nicht nennen, weil am nächsten Aufruf der Funktion, Du könnte finden Sie Ihre Behälter noch am Leben ist, und die Handler werden aufgerufen, mit ein bereits geschlossener Datenbankhandle

Sie müssen Lambda-Funktionen schreiben, so dass sie weder fehlschlagen, wenn ein Container wiederverwendet wird, noch fehlschlagen, wenn ein Container nicht wiederverwendet wird.

Die einfachere Lösung besteht darin, die DB-Verbindung innerhalb des Handlers zu öffnen. Die komplexere, aber auch optimale Lösung (in Bezug auf die Laufzeit) besteht darin, sie niemals zu schließen, sodass sie möglicherweise wiederverwendet werden kann.

+0

Danke @Michael. Die offene DB-Verbindung wurde in den Handler verschoben und es funktioniert jetzt einwandfrei. – Jay

Verwandte Themen