Очистка после AWS Лямбда-контекст выполнения закрывается с Python - PullRequest
1 голос
/ 05 марта 2020

Из рекомендаций по работе с AWS лямбда-функциями :

Воспользуйтесь преимуществами повторного использования контекста выполнения для повышения производительности вашей функции. Инициализация клиентов SDK и соединений с базой данных вне обработчика функций, [...]

Я хотел бы реализовать этот принцип для улучшения моей лямбда-функции, где дескриптор базы данных инициализируется и закрывается каждый раз функция вызывается. Возьмите следующий пример:

def lambda_handler(event, context):
    # Open a connection to the database
    db_handle = connect_database()    

    # Do something with the database
    result = perform_actions(db_handle)  

    # Clean up, close the connection
    db_handle.close()       

    # Return the result
    return result    

Исходя из моего понимания документации AWS, код должен быть оптимизирован следующим образом:

# Initialize the database connection outside the handler
db_handle = conn_database()

def lambda_handler(event, context):
    # Do something with the database and return the result
    return perform_actions(db_handle)

Это приведет к методу db_handle.close() не вызывается, что может привести к утечке соединения.

Как мне выполнить очистку таких ресурсов при использовании AWS Lambda с Python?

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Многие люди ищут то же самое с вами. Я считаю, что это невозможно в это время. Но мы могли бы решить проблему со стороны базы данных.

Взгляните на этот

0 голосов
/ 07 марта 2020

утечка соединения может произойти только тогда, когда Лямбда-среда исполнения имеет значение жив ; другими словами, соединение будет timeout (закрыто) после разрушения среды выполнения.

Является ли объект глобального соединения стоящим для реализации , зависит от вашего конкретного варианта использования:
- сколько общего времени выполнения занимает инициализация базы данных
- как часто Ваша функция называется
- как вы обрабатываете ошибки соединения с базой данных

Если вы хотите иметь немного больше контроля над соединением, вы можете попробовать этот подход, который перерабатывает соединение с базой данных каждый раз два часа или при обнаружении исключений , связанных с базой данных :

# Initialize the global object to hold database connection and timestamp
db_conn = {
    "db_handle": None,
    "init_dt": None
}

def lambda_handler(event, context):
    # check database connection
    if not db_conn["db_handle"]:
        db_conn["db_handle"] = connect_database()
        db_conn["init_dt"] = datetime.datetime.now() 
    # Do something with the database and return the result
    try:
        result = do_work(db_conn["db_handle"])
    except DBError:
         try:
             db_conn["db_handle"].close()
         except:
             pass
         db_conn["db_handle"] = None
         return "db error occured"      
    # check connection age
    if datetime.datetime.now() - db_conn["init_dt"] > datetime.timedelta(hours=2):
         db_conn["db_handle"].close()
         db_conn["db_handle"] = None
    return result

Обратите внимание, что я не проверял вышеупомянутое на Lambda, поэтому вам необходимо проверить его с настройками.

...