postgresql 连接客户端存在 CLOSE_WAIT、TIME_WAIT 状态
ssh 192.168.56.100
# netstat -antp|grep -i "5672" |grep -v "ESTABLISHED"
tcp 1 0 192.168.56.100:52674 192.168.56.150:5672 CLOSE_WAIT 116553/postgres: pe
tcp 1 0 192.168.56.100:37251 192.168.56.150:5672 CLOSE_WAIT 46480/postgres: pei
tcp 1 0 192.168.56.100:47048 192.168.56.150:5672 CLOSE_WAIT 118735/postgres: pe
tcp 95 0 192.168.56.100:56547 192.168.56.150:5672 CLOSE_WAIT 94628/postgres: pei
tcp 0 0 192.168.56.100:55290 192.168.56.150:5672 TIME_WAIT -
网络状态细节可以baidu,这里只是简单描述下
CLOSE_WAIT 被动关闭
192.168.56.150端关闭连接之后,本地已经接收到FIN,但是还没有发送自己的FIN的时刻,连接处于CLOSE_WAIT状态。
这个资源就一直被程序占着。
TIME_WAIT 主动关闭
192.168.56.100端主动关闭连接的一方保持的状态,
解决思路就是让服务器能够快速回收和重用那些TIME_WAIT的资源。
TIME_WAIT 状态可以通过调整os和postgresql的参数来优化
1)os参数
# sysctl -a |grep -i tcp_keepalive
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 600
附上系统的默认值
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 7200
2)postgresql 参数
select ps.name,ps.setting,ps.unit,ps.category,ps.short_desc
from pg_settings ps
where 1=1
and ps.category like '%Client Connection Defaults / Other Defaults%'
;
name | setting | unit | category | short_desc
-------------------------+---------+------+---------------------------------------------+----------------------------------------------------------
dynamic_library_path | $libdir | | Client Connection Defaults / Other Defaults | Sets the path for dynamically loadable modules.
gin_fuzzy_search_limit | 0 | | Client Connection Defaults / Other Defaults | Sets the maximum allowed result for exact search by GIN.
local_preload_libraries | | | Client Connection Defaults / Other Defaults | Lists shared libraries to preload into each backend.
tcp_keepalives_count | 0 | | Client Connection Defaults / Other Defaults | Maximum number of TCP keepalive retransmits.
tcp_keepalives_idle | 0 | s | Client Connection Defaults / Other Defaults | Time between issuing TCP keepalives.
tcp_keepalives_interval | 0 | s | Client Connection Defaults / Other Defaults | Time between TCP keepalive retransmits.
(6 行记录)
tcp_keepalives_idle (integer)
指定不活动多少秒之后通过 TCP 向客户端发送一个 keepalive 消息。
0 值表示使用默认值。
这个参数只有在支持 TCP_KEEPIDLE 或 TCP_KEEPALIVE 符号的系统或 Windows 上才可以使用。
在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,这个参数被忽略并且总是读作零。
注意: 在 Windows 上,值若为 0,系统会将该参数设置为 2 小时,因为 Windows 不支持读取系统默认值。
tcp_keepalives_interval (integer)
指定在多少秒之后重发一个还没有被客户端告知已收到的 TCP keepalive 消息。
0 值表示使用系统默认值。
这个参数只有在支持TCP_KEEPINTVL符号的系统或 Windows 上才可以使用。
在其他系统上,必须为零。在通过 Unix域套接字连接的会话中,这个参数被忽略并总被读作零。
注意: 在 Windows 上,值若为 0,系统会将该参数设置为 1 秒,因为 Windows 不支持读取系统默认值。
tcp_keepalives_count (integer)
指定与客户端的服务器连接被认为死掉之前允许丢失的 TCP keepalive 数量。
0 值表示使用系统默认值。
这个参数只有在支持TCP_KEEPCNT符号的系统上才可以使用。
在其他系统上,必须为零。在通过 Unix 域套接字连接的会话中,这个参数被忽略并总被读作零。
注意: Windows 不支持该参数,且必须为零。
postgresql 如果参数 tcp_keepalives_count、tcp_keepalives_idle、tcp_keepalives_interval 设置为非0值,则使用postgresql 参数值,否则使用os对应的参数值
参数对应关系,第一列为postgresql参数,第二列为os参数
tcp_keepalives_idle tcp_keepalive_time
tcp_keepalives_interval tcp_keepalive_intvl
tcp_keepalives_count tcp_keepalive_probes