Python gremlin连接Neptune报Connection was already closed如何解决
问题根因
当前重试逻辑没有覆盖抛出的RuntimeError类型错误,导致backoff装饰器不会捕获该错误,也不会触发后续的重连逻辑,具体原因有两个:
- 可重试异常列表
retriable_errors中仅包含GremlinServerError、WebSocketClosedError、OSError三类,未包含本次报错的RuntimeError - 可重连错误关键字列表
reconnectable_err_msgs中没有匹配Connection was already closed的规则,即使后续判断错误内容也无法识别为需要重连的场景
修复方案
- 第一步:修改
db.py中的可重试异常列表,将RuntimeError纳入捕获范围
# 原代码 retriable_errors = [GremlinServerError] + network_errors # 修改后 retriable_errors = [GremlinServerError, RuntimeError] + network_errors
- 第二步:在可重连错误信息列表中添加对应错误关键字,确保触发连接重置逻辑
# 原代码 reconnectable_err_msgs = [ 'ReadOnlyViolationException', 'Server disconnected', 'Connection refused' ] # 修改后 reconnectable_err_msgs = [ 'ReadOnlyViolationException', 'Server disconnected', 'Connection refused', 'Connection was already closed' ]
- 可选优化(适配无服务器/高并发场景):将全局连接改为懒加载模式,避免模块初始化时创建的连接长时间闲置被Neptune服务端主动断开,同时降低多请求并发时的连接重置竞态问题
# 替换原模块级的conn、g初始化逻辑 conn = None g = None def get_graph_traversal(): global conn, g if conn is None or g is None: conn = create_remote_connection() g = create_graph_traversal_source(conn) return g
业务查询代码同步修改调用方式,将直接引用db.g改为调用get_graph_traversal()获取遍历对象:
@backoff.on_exception(backoff.constant, tuple(db.retriable_errors), max_tries=5, jitter=None, giveup=db.is_non_retriable_error, on_backoff=db.reset_connection_if_connection_issue, interval=1) def is_user_available(event): logging.debug("check the user from Neptune") return db.get_graph_traversal().V(cognito_username).hasNext()
内容的提问来源于stack exchange,提问作者Thirumal
相关产品推荐
相关产品推荐

