1. 程式人生 > >TCP keepalive長連接心跳保活

TCP keepalive長連接心跳保活

line 成功 https 頻率 之前 bin 發現 nbsp 進入


比如:客戶端與服務端進行握手時,經常無法握手成功,收不到回復; 需要建立保活機制。

1. 服務端Linux服務器新增系統內核參數配置。

在/etc/sysctl.conf文件中再添加如:

#允許的持續空閑時長,在TCP保活打開的情況下,最後一次數據交換到TCP發送第一個保活探測包的間隔,即允許的持續空閑時長,或者說每次正常發送心跳的周期,默認值為7200s(2h)。
net.ipv4.tcp_keepalive_time=1800
#在tcp_keepalive_time之後,沒有接收到對方確認,繼續發送保活探測包的發送頻率,
net.ipv4.tcp_keepalive_intvl=30
#在tcp_keepalive_time之後,沒有接收到對方確認,繼續發送保活探測包次數
net.ipv4.tcp_keepalive_probes
=3

執行sysctl -p來使它生效:
檢測一下是否已經生效:sysctl -a | grep keepalive

2. Java/netty服務器中配置使用

ServerBootstrap bootstrapHttp =new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
bootstrapHttp.setPipelineFactory(new HttpServerPipelineFactory());
bootstrapHttp.setOption(
"child.tcpNoDelay", true); bootstrapHttp.setOption("child.keepAlive", true); bootstrapHttp.bind(new InetSocketAddress(ip, http_port));

3.關閉tcp_timestamps選項

客戶在服務端開啟了某個端口,但是在客戶端telnet確一直不通。通過在服務端抓包發現,客戶端的syn分節已經到達,但是服務端並沒有應答。
net.ipv4.tcp_tw_recycle選項可能引起這個問題,於是關閉了這個選項,問題果然得以解決。這裏分析一下原因。
有些服務器(當然客戶端也可以)為了避免TIME_WAIT狀態占用連接,希望能加快TIME_WAIT狀態的回收,通常將net.ipv4.tcp_tw_recycle選項開啟。
當然這個選項的生效要依賴net.ipv4.tcp_timestamps選項的開啟。雖然開啟這個選項能夠加快TIME_WAIT連接的回收,但卻引入了另一個問題。我們先看下tcp_tw_recycle選項的工作機制:
當開啟了tcp_tw_recycle選項後,當連接進入TIME_WAIT狀態後,會記錄對應遠端主機最後到達分節的時間戳。如果同樣的主機有新的分節到達,且時間戳小於之前記錄的時間戳,即視為無效,相應的數據包會被丟棄(rfc1323)。
Linux是否啟用這種行為取決於tcp_timestamps和tcp_tw_recycle,因為tcp_timestamps缺省就是開啟的,所以當tcp_tw_recycle被開啟後,實際上這種行為就被激活了

在/etc/sysctl.conf文件中再添加如:
#不檢查請求的時間戳

net.ipv4.tcp_timestamps=0

TCP keepalive長連接心跳保活