維護TCP長鏈接時系統配置的參數net.ipv4.tcp_keepalive_time不生效

背景

項目中常常使用LVS作負載,當一個長鏈接的過段時間不發消息時,LVS以後就不會再轉發這個長鏈接的TCP數據包。後端

使用TCP長鏈接的場景

一種狀況:爲了節省TCP鏈接時間,咱們選擇創建幾個固定的TCP長鏈接,而後把全部的消息平均分配的這幾個TCP通道上傳送給對方。
另外一種狀況:客戶端和服務端之間是一個會話,要隔一段時間發個心跳。
bash

如今出現了第三種狀況,我是一個代理程序,要轉發一個會話,讓服務端和客戶端都無感知;並且多個會話能夠複用一個通路
(1)我須要在會話創建以前就創建鏈接;
(2)沒設計代理的心跳接口,我不能本身給後端發心跳;
但代理和後端之間隔着LVS。我不發心跳,LVS就偷偷地把長鏈接斷開了,而此時代理和後端都一無所知。從鏈接上看都是ESTABLISHED,一發消息就被RST。


tcp

這時咱們就用到了TCP自帶的keepalive機制。spa

配置TCP長鏈接參數

在Centos7上的嘗試,配置如下內核參數設計

# cat /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_keepalive_probes = 2 
net.ipv4.tcp_keepalive_intvl = 20

可是沒見生效,在C++的程序中也開啓此機制:(也就是說得讓系統知道你是長鏈接)代理

int keepAlive = 5;
int keepIdle = 5;
int keepInterval = 5;
int keepCount = 3;

if(setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)
{
	printf("setsockopt SO_KEEPALIVE error!");
}

那發送間隔等參數的設置,最後以誰爲準呢?
答:/etc/sysctl.conf中配置的參數爲準。
code

相關文章
相關標籤/搜索