Итак, я создал этот 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).