我正在使用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
的套接字。我们可以使用unix ss
命令检查套接字。 (您也可以使用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参数。
答案 0 :(得分:1)
来自PostgreSQL文档:
控制在客户端与服务器的连接被视为无效之前可能丢失的TCP Keepalive的数量。值为零使用系统默认值。对于通过Unix域套接字建立的连接,或者如果禁用了keepalive,将忽略此参数。它仅在TCP_KEEPCNT套接字选项可用的系统上受支持;在其他系统上,它没有任何效果。
换句话说。如果您的系统不支持它,则它不起作用,并且将应用正常的超时规则。