我正在使用 sqlalchemy 创建与 postgresql 的连接并执行简单的命令。
>>> from sqlalchemy import create_engine
>>> c = create_engine('postgres://myuser@myremoteserver/mydb?keepalives_idle=4&keepalives_interval=1&keepalives_count=5')
>>> c.execute('select 1').scalar()
1
它工作正常。
在执行查询时创建连接后,它将创建到 postgres 服务器的套接字,在此示例中,它将创建到myremoteserver
. 我们可以使用 unixss
命令检查套接字。(您也可以使用netstat
)。
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,1.319ms,0) users:(("python",4074,3))
如果在创建连接后网络出现故障或 postgres 服务器机器崩溃。
>>> c = create_engine('postgres://myuser@myremoteserver/mydb?keepalives_idle=4&keepalives_interval=1&keepalives_count=5')
(您可以ifdown eth0
对myremoteserver
网络关闭进行操作)
然后它将在 5 次尝试到服务器后关闭连接。
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,1.319ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,738ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,2.720ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,788ms,2) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 0 192.168.1.15:43471 myremoteserver:postgres timer:(keepalive,191ms,4) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
[root@myclient ~]# ss -torp | grep python
这是我们在连接字符串中设置的连接行为。
如果我们在套接字关闭和服务器关闭之前执行查询,就会出现问题。
# do ifdown eth0 on postgres server to break the network connection.
# execute query before socket close.
>>> c.execute('select 1').scalar()
现在如果你检查套接字然后
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,1.602ms,3) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,585ms,3) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,2.833ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,1.851ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,808ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,5.393ms,5) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,3.846ms,5) users:(("python",3098,7))
.................
.................
.................
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,5.268ms,72) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB 0 74 192.168.1.15:43471 myremoteserver:postgres timer:(on,4.804ms,254) users:(("python",3098,7))
根据连接字符串套接字必须在 5 次尝试后关闭。但我不知道为什么它尝试了 5 次以上并达到 254 次尝试。
即使我们在服务器崩溃和客户端关闭套接字之间执行查询,我必须设置什么才能在 5 次尝试后关闭套接字。
注意:keepalives_idle、keepalives_interval 和 keepalives_count 用于设置 TCP 连接中的 keepalive 参数。