tcp 長鏈接與短鏈接

長鏈接與短鏈接

  • 使用TCP協議時,會在客戶端和服務器之間創建一條虛擬的信道,這條虛擬信道就是指鏈接,而建議這條鏈接須要3次握手,拆毀這條鏈接須要4次揮手,可見,咱們創建這條鏈接是有成本的,這個成本就是效率成本,簡單點說就是時間成本,你要想發送一段數據,必須先3次握手(來往3個包),而後才能發送數據,發送完了,你須要4次揮手(來往4個包)來斷開這個鏈接。
  • 其二,CPU資源成本,三次握手和4次揮手和發送數據都是從網卡里發送出去和接收的,還有其他的設備,好比防火牆,路由器等等,站在操做系統內核的角度來說,若是咱們是一個高併發系統的話,若是大量的數據包都經歷過這麼一個過程,那是很耗CPU的。
  • 其三,每一個socket是須要耗費系統緩存的,好比系統提供了一些接口設置socket緩存的,好比:
/proc/sys/net/ipv4/tcp_rmem
/proc/sys/net/ipv4/tcp_wmem
/proc/sys/net/ipv4/tcp_mem

keepalive機制

TCP鏈接一旦創建後,是否是這個鏈接能夠一直保持? 答案是否認的,操做系統在實現TCP協議的時候都作了一個限制,這個限制能夠參考配置:緩存

cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes
  • 咱們看到默認這個tcp_keepalive_time的值爲7200s,也就是2個小時,這個值表明若是TCP鏈接發送完最後一個ACK包後,若是超過2個小時,沒有數據往來,那麼這個鏈接會斷掉。那麼咱們如何才能保持住這個鏈接呢?實際上,這就是TCP的keepalive機制,哦,說法不嚴謹,TCP協議並無規定如此,可是不少的操做系統內核實現TCP協議時,都加上了這個keepalive機制,那麼這個功能默認是關閉的,那這個keepalive機制究竟是如何的呢?也就是,若是TCP之間沒有任何數據來往了在tcp_keepalive_time(7200s,2h)後,服務器給客戶端發送一個探測包,若是對方有迴應,說明這個鏈接還存活,不然繼續每隔tcp_keepalive_intvl(默認爲75s)給對方發送探測包,若是連續tcp_keepalive_probes(默認爲9)次後,依然沒有收到對端的回覆,那麼則認爲這個鏈接已經關閉。
  • tcp keepalive默認不是開啓的,若是想使用KeepAlive,須要在你的應用中設置SO_KEEPALIVE才能夠生效。固然事先咱們能夠修改這些默認值,方法以下:

在Linux中咱們能夠經過修改 /etc/sysctl.conf 的全局配置:服務器

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

添加上面的配置後輸入 sysctl -p 使其生效,你可使用 sysctl -a | grep keepalive 命令來查看當前的默認配置併發

tcp keepalive能夠經過設置TCP選項設置,設置方法以下:socket

#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);

咱們在須要使能Keepalive的socket上面調用setsockopt函數即可以打開該socket上面的keepalive。tcp

第一個參數是要設置的套接字 第二個參數是SOL_SOCKET 第三個參數必須是SO_KEEPALIVE 第四個參數必須是一個布爾整型值,0表示關閉,1表示打開 最後一個參數是第四個參數值的大小。函數

示例:高併發

int keepalive = 1;
 setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));
                         
 int keepalive_time = 30;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));
 int keepalive_intvl = 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));
int keepalive_probes= 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));

設置SO_KEEPALIVE選項來開啓KEEPALIVE,而後經過TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT設置keepalive的保活時間、間隔、次數等參數。操作系統

相關文章
相關標籤/搜索