Python SQLAlchemy SSL系统调用超时应对机制

Python SQLAlchemy SSL系统调用超时应对机制,python,database,ssl,networking,sqlalchemy,Python,Database,Ssl,Networking,Sqlalchemy,我正在使用SQLAlchemy和Postgres的组合。我想,每隔一段时间,我的数据库集群就会替换一个失败的节点,这就是生命周期 我的印象是,通过以下方式配置我的引擎: engine = create_engine( env_config.pg_connection_string, echo=False, pool_size=env_config.pg_pool_size, pool_timeout=1, # Number of seconds to wait

我正在使用SQLAlchemy和Postgres的组合。我想,每隔一段时间,我的数据库集群就会替换一个失败的节点,这就是生命周期

我的印象是,通过以下方式配置我的引擎:

engine = create_engine(
    env_config.pg_connection_string,
    echo=False,
    pool_size=env_config.pg_pool_size,
    pool_timeout=1,  # Number of seconds to wait before giving up on getting a connection from the pool.
    pool_recycle=3600,  # Replace connections on CHECKOUT after 1 hour
    connect_args={
        'connect_timeout': 10,  # Maximum wait for connection
        "options": "-c statement_timeout=30s"  # Maximum amount of time set for statements
    },
)
如果查询时间大于30秒,我的连接将超时,尝试10秒后,我的连接将超时

我在实践中注意到的是,在从我的db集群替换我的db节点的情况下,有时需要15分钟(900秒)处理异常,如
psycopg2.DatabaseError:SSL系统调用错误:没有到主机的路由
。如果在替换节点时db事务处于活动状态,则它最多需要16分钟来引发SYSCALL异常。所有新的事务都得到了很好的处理,我想路由到了正确的主机?但现有的会话/事务似乎会阻塞并停止长达16分钟

我的解释是,SSL系统调用问题既不是连接,也不是与语句相关的设置,因此两个配置的超时都不会产生影响。我的问题仍然是“如何停止或超时这些SSL系统调用问题?”,我宁愿快速失败并重试同一个查询,也不愿花15分钟阻止调用。我不确定该在哪里解决这个问题,我猜测是在我的数据库层(Postgres、SQLAlchemy或DB驱动程序)中,还是在我的网络层(Centos)中进行配置


在我的postgres配置中进一步挖掘发现,postgres中
TCP\u keepalives\u count
TCP\u keep\u alives\u interval
的TCP相关设置分别为6和10。这让我们想知道为什么60秒后连接没有被切断。此外,即使没有“到主机的路由”,也有可能接收TCP确认,即SSL系统调用问题。

除非其他人有更合适的解释,否则我确信我的问题是由TCP
TCP_重试2
和未正常停止打开的db连接的组合造成的。每当我的主db节点被替换时,它将从集群中取消,与该节点建立的任何连接都将保持打开/处于建立状态。使用当前的默认TCP设置,可能需要15分钟才能断开连接,但不确定为什么会出现
SSL系统调用
异常

在PGbounder repo:的一个问题/PR中,涵盖了我的问题的这个问题得到了很好的解决,TCP连接在标记/认为“死”之前花费了很长时间

我建议阅读该页面以便更好地理解,我的假设是我的问题也是由默认TCP设置引起的

长话短说,我认为有两种选择:

  • 在我的主机上手动调整TCP设置,这将影响该计算机上所有其他使用TCP的组件
  • 设置类似PGBouncer的内容,以便TCP调优可以在本地完成,而不会影响该计算机上的任何其他内容

  • 您可以根据每个连接自定义TCP设置。看到这条线了吗?