偶爾有使用者會遇到遠端程式連接配接rds pg,在不做任何操作一段時間後可能中斷。
其實可能是使用者和rds pg之間,某些網絡裝置設定了會話空閑逾時,會主動中斷會話。
那麼有什麼方法能解決這個問題呢?
運維的同學可能有這方面的經驗,例如使用securecrt或者其他終端連接配接伺服器時,可以設定這些管理工具的no-op,周期性的發一些空字元過去,保證會話上有流量。
但是資料庫連接配接怎麼搞呢?
postgresql提供了tcp keep alive的參數可供使用者設定。
為了避免會話中斷的問題, 可以通過tcp層的keepalive機制來達到傳輸心跳資料的目的.
方法一,設定資料庫參數
postgresql支援會話級别的設定, 資料庫級别的設定在$pgdata/postgresql.conf,
建議設定如下三個參數的值
解釋詳見本文末尾[參考1].
代碼詳見本文末尾[參考2].
參數解釋
tcp_keepalives_idle : 定義這個tcp連接配接間隔多長後開始發送 第一個 tcp keepalive 包.
tcp_keepalives_interval : 定義在以上發送第一個tcp keepalive包後如果在這個時間間隔内沒有收到對端的回包, 則開始發送第二個tcp keepalive包. 在這個時間内再沒有回包的話則發送第三個keepalive包....直到達到tcp_keepalives_count次則broken 連接配接.
tcp_keepalives_count : 定義一共發送多少個tcp keepalive包, 達到這個數字後如果對端都沒有回響應包, 則關閉這個連接配接.
另外需要注意的是, 這幾個postgresql參數對postgresql資料庫服務端的backend process生效.
是以如果發出第一個keepalive包後, 在tcp_keepalives_interval秒内有用戶端回包, 則又回到tcp_keepalives_idle計數(注意此時計數是tcp_keepalives_idle 減去 tcp_keepalives_interval 秒).
例如 :
client (172.16.3.33) :
查找資料庫端對應的process id.
server (172.16.3.150) :
在資料庫端檢視keepalive timer
在用戶端檢視keepalive timer
繼承了作業系統的keepalive設定
通過tcpdump可以觀察間隔一定的時間, 會發出keepalive包.
方法二、設定作業系統級的參數:
設定client伺服器系統級的keepalive, 然後重新連接配接到資料庫, 看看用戶端的keepalive timer會不會發生變化
系統層設定的keepalive已經生效了.
.1.
通過tcpdump觀察keepalive包, 也可以将這些包抓下來通過wireshark檢視.
每個sock會話, 每隔13秒, 資料庫服務端會發送心跳包.
.2.
由于每個tcp會話都需要1個計時器, 是以如果連接配接數很多, 開啟keepalive也是比較耗費資源的.
可以使用setsockopt關閉該會話keepalive的功能. 下一篇blog介紹如何禁用keepalive.
.3.
如果tcp_keepalives_idle小于tcp_keepalives_interval, 那麼間隔多長時間發1個心跳包呢?
例如tcp_keepalives_idle=2, tcp_keepalives_interval=10.
答案是10, 因為檢查計時需要10秒.
.2. /usr/share/doc/kernel/documentation/networking/ip-sysctl.txt
.3. src/backend/libpq/pqcomm.c
.4. man netstat
.5. man 7 tcp
.6. netstat core :
以下内容轉載自 :
<a href="http://vzkernel.blogspot.tw/2012/09/description-of-netstat-timers.html">http://vzkernel.blogspot.tw/2012/09/description-of-netstat-timers.html</a>