Как заставить AWS Lambda надежно работать с Neptune через веб-сокеты?

Итак, я создал этот API. Он состоит из лямбда-функции (доступной через API-шлюз), которая общается с экземпляром базы данных графа Нептуна через веб-сокеты.

Все подключено и работает. Но недавно я начал замечать, что от API приходят прерывистые 500. После некоторого расследования я обнаружил, что сервер Neptune Gremlin сбрасывает / отклоняет соединения всякий раз, когда несколько запросов приходят близко друг к другу.

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

На странице также предлагается, что при использовании Gremlin на Нептуне вам, вероятно, следует отправлять HTTP-запросы в Нептун, а не использовать веб-сокеты,

В качестве альтернативы, если вы используете Gremlin, рассмотрите возможность отправки запросов в конечную точку Gremlin HTTP REST, а не в конечную точку WebSockets, тем самым избегая необходимости создавать и управлять временем жизни пула соединений.

Обратной стороной этого подхода является то, что тогда нам придется использовать строковые запросы (что означает переписывание большой части проекта). Еще одним недостатком является то, что конечная точка HTTP Gremlin возвращает довольно неструктурированные данные.

Так что мне интересно, есть ли у кого-нибудь надежная связь Lambda с Нептуном через веб-сокеты? Если да, то как?

Редактировать:

Поскольку я использую платформу AWS Chalice, я не думаю, что у меня действительно есть прямой доступ к функции обработчика. Вот как выглядит моя лямбда.

введите здесь описание изображения

А вот код, который вызывает connect():

import os

from gremlin_python.structure.graph import Graph
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection


def connect():
    conn_string = os.environ.get('GRAPH_DB')
    global g
    g = Graph().traversal().withRemote(DriverRemoteConnection(conn_string, 'g'))

Поэтому, когда приложение запускается (когда запускается экземпляр лямбда-выражения), вызывается эта функция подключения, и приложение устанавливает соединение с Neptune. Оттуда приложение передает эту глобальную переменную g, чтобы использовать тот же экземпляр соединения для этого вызова. Затем я вызвал close() для объекта DriverRemoteConnection перед возвратом результатов запроса (и именно там я обнаружил, что все еще получаю 500).


person jordanmmck    schedule 03.06.2020    source источник


Ответы (1)


Да, можно использовать WebSockets в функции Lambda для связи с Neptune. Для этого существуют разные нюансы в зависимости от используемого вами языка программирования. В конечном итоге все сводится к созданию экземпляра клиентского соединения и закрытию соединения в обработчике () функции Lambda.

При использовании Java [1] вы можете создать объект кластера вне обработчика, чтобы его можно было повторно использовать при каждом вызове Lambda. Но клиент, который настроен из этого кластерного объекта, должен быть создан и закрыт во время каждого вызова.

У вас есть фрагмент кода, который вы используете, чтобы поделиться им для проверки?

[1] https://docs.aws.amazon.com/neptune/latest/userguide/best-practices-gremlin-java-close-connections.html

person Taylor Riggan    schedule 03.06.2020
comment
Спасибо за ответ. Ситуация может осложняться тем фактом, что я использую фреймворк Chalice, поэтому у меня нет прямого доступа к функции-обработчику. Я отредактирую сообщение, добавив некоторую дополнительную информацию. - person jordanmmck; 04.06.2020
comment
В целом, вам необходимо убедиться, что каждый раз, когда вызывается функция Lambda, создается новое соединение, а затем закрывается. С точки зрения Chalice, это означает, что каждый раз, когда выполняется вызов API к маршруту внутри Chalice Lambda. Поэтому вместо того, чтобы выполнять connect () на верхнем уровне, вы захотите вызвать его в каждом маршруте и закрыть соединение в конце каждого вызова маршрута / API. - person Taylor Riggan; 04.06.2020
comment
Хорошо, отлично, я попробую это! - person jordanmmck; 04.06.2020
comment
Кажется, это решение работает! Большое спасибо, Тейлор! - person jordanmmck; 04.06.2020