2017-04-11 19 views
0

AWS RDS(MySQL)に接続しようとすると、ほとんどの場合、私はInterfaceErrorを受け取ります。ラムダコードを編集して再実行すると、初めてうまく動作しますが、同じエラーが発生します。AWSラムダRDS MySQL DB接続インターフェイスエラー

マイコード:

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()を呼び出すことはありません、ハンドラの外あなたのDB接続をやろうとしている場合は、あなたあなたのコンテナがまだ生きている、そしてハンドラがで呼び出されるかもしれません既に閉じられているデータベースハンドルです。

ラムダ関数は、コンテナが再利用されても失敗したり、コンテナが再利用されないと失敗したりしないように記述する必要があります。

より単純な解決策は、ハンドラの内部でDB接続を開くことです。より複雑でありながらより最適なソリューション(ランタイムの点で)は、決してそれを閉じることがないため、潜在的に再利用される可能性があります。

+0

ありがとう@Michael。オープンDB接続をハンドラ内で移動しました。 – Jay

関連する問題