学会Linux Keeplive,保持网络连接不中断 (linux keeplive)

在网络通信中,保持网络连接的稳定性是非常重要的,这样可以有效避免网络连接中断带来的不良影响。而Linux Keeplive技术可以有效的保持网络连接的稳定性,本文就来介绍一下在Linux系统中如何使用Keeplive技术,实现网络连接不中断的方法。

一、什么是Linux Keeplive技术

Keeplive技术是一种用于保持网络连接存活的技术。当网络连接正常的时候,Keeplive技术会定期向网络连接的另一端发送心跳包,以确保网络连接的活性。当网络连接异常断开时,Keeplive技术可以快速地检测到网络连接的中断,并进行重新连接,从而达到保持网络连接不中断的目的。

在Linux系统中,Keeplive技术主要是通过TCP_KEEPALIVE属性实现的。TCP_KEEPALIVE属性是一种可选的TCP属性,它可以用于指定TCP会话的存活时间,并且可以控制TCP会话在未发生任何数据包传输的情况下的保活时间,从而保持TCP连接的有效性。

二、如何开启Linux Keeplive技术

在Linux系统中,开启Keeplive技术可以通过TCP_KEEPALIVE属性来实现。下面是如何开启TCP_KEEPALIVE属性的方法。

打开/etc/sysctl.conf文件,可以使用vim或其他编辑器打开该文件,然后在文件末尾添加如下内容:

net.ipv4.tcp_keepalive_intvl = 30

net.ipv4.tcp_keepalive_probes = 3

net.ipv4.tcp_keepalive_time = 120

这三个参数的含义如下:

– tcp_keepalive_intvl 指定心跳包的发送间隔时间,单位为秒,默认为75秒。

– tcp_keepalive_probes 指定发送的心跳包的数量,超过这个数量后还未收到回应,则认为连接已经断开,默认为9个。

– tcp_keepalive_time 指定TCP会话的存活时间,当会话的存活时间超过指定的时间后,系统会向连接的另一端发送心跳包,以检测连接是否正常。

这样就成功开启TCP_KEEPALIVE属性了。

三、Keeplive技术的其他应用

除了在网络连接中保持稳定性外,Keeplive技术还可以应用于其他方面。比如说在服务器上,可以利用Keeplive技术来监测服务器内存的稳定性,以及监测磁盘读写、网络下载和上传速度等。

在实际使用中,开启Keeplive技术可以有效地保持网络连接的稳定性,从而避免出现因连接中断而造成的不良影响。对于大型的网站和网络应用来说,Keeplive技术更是非常重要,它可以帮助用户保持连接,并提高网络应用的稳定性和可靠性。

学会Keeplive技术对于Linux用户来说是非常有用的。Linux系统中提供了很多工具和方法来实现Keeplive技术,可以根据自己的实际需求进行选择和使用。开启Keeplive技术可以使网络连接更加稳定,并保证网络应用的正常运行,是一项非常重要的技术。

相关问题拓展阅读:

linux socket怎么检测断开

我想通过recv和send的返回值来判断是否连接异常,但是不成功,下面是我的测试代码,连接成功后如果我断开客户端,那么服务端不会打印错误信息而是等待几秒后直接终止;如果断开服务端,客户端的recv不再阻塞,而且返回值一直是0,请高手指点。

C/C++ code//服务端

#include

#include

#include

#include

#include

#include

#include

#include

#define MYPORT 3490 /*定义用户连接端口*/

#define BACKLOG 10 /*多少等待连接控制*/

int main(int argc, char *argv)

{

int sockfd, new_fd;/* listen on sock_fd, new connection on new_fd*/

struct sockaddr_in my_addr; /* my address information */

struct sockaddr_in their_addr; /* connector’s address information */

int sin_size;

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror(“socket”);

exit(1);

}

int opt = 1;

int len = sizeof(opt);

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, len);

my_addr.sin_family = AF_INET; /* host byte order */

my_addr.sin_port = htons(MYPORT); /* short, network byte order */

my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */

bzero(&(my_addr.sin_zero),0); /* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1)

{

perror(“bind”);

exit(1);

}

if (listen(sockfd, BACKLOG) == -1) {

perror(“listen”);

exit(1);

}

while(1) { /* main accept() loop */

sin_size = sizeof(struct sockaddr_in);

printf(“while\n”);

if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)

{

perror(“accept”);

continue;

}

printf(“server: got connection from %s\n”, inet_ntoa(their_addr.sin_addr));

while(1)

{

usleep();

if (send(new_fd, “Hello, world!\n”, 14, 0) == -1)

perror(“send”);

}

close(new_fd);

exit(0);

}

return 0;

}

C/C++ code//客户端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 3490 /* 客户机连接远程主机的端口 */

#define MAXDATASIZE 100 /* 每次可以接收的更大字节 */

int main(int argc, char *argv)

{

int sockfd, numbytes;

char buf;

struct hostent *he;

struct sockaddr_in their_addr; /* connector’s address information */

if (argc != 2)

{

fprintf(stderr,”usage: client hostname\n”);

exit(1);

}

if ((he=gethostbyname(argv)) == NULL)

{ /* get the host info */

herror(“gethostbyname”);

exit(1);

}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror(“socket”);

exit(1);

}

their_addr.sin_family = AF_INET; /* host byte order */

their_addr.sin_port = htons(PORT); /* short, network byte order */

their_addr.sin_addr = *((struct in_addr *)(he->h_addr));

bzero(&(their_addr.sin_zero),0); /* zero the rest of the struct */

if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1)

{

perror(“connect”);

exit(1);

}

while(1)

{

printf(“receiving……\n”);

if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)

{

perror(“recv”);

exit(1);

}

buf = ‘\0’;

printf(“Received: %s\n”,buf);

}

close(sockfd);

return 0;

}

另外,在网上看到一种利用TCP协议栈中的KeepAlive探测的方法,下面是我从网上找的用的比较多的一段代码,这里应该只是设置了一些属性参数,但不知具体怎样在通信中检测断开,请高手赐教。

C/C++ code#include

……

////KeepAlive实现

//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口

int keepAlive = 1;//设定KeepAlive

int keepIdle = 5;//开始首次KeepAlive探测前的TCP空闭时间

int keepInterval = 5;//两次KeepAlive探测间的时间间隔

int keepCount = 3;//判定断开前的KeepAlive探测次数

if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT (“(%P|%t) setsockopt SO_KEEPALIVE error!\n”)));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT (“(%P|%t) setsockopt TCP_KEEPIDLE error!\n”)));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT (“(%P|%t) setsockopt TCP_KEEPINTVL error!\n”)));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT (“(%P|%t)setsockopt TCP_KEEPCNT error!\n”)));

linux内核优化参数

作为高性能WEB服务器,只调整Nginx本身的参数是不行的,因为Nginx服务依赖于高性能的操作系统。

以下为常见的几个Linux内核参数优化方法。

net.ipv4.tcp_max_tw_buckets

对于tcp连接,服务端和客户端通信完后状态变为timewait,假如某台服务器非常忙,连接数特别多的话,那么这个timewait数量就会越来越大。

毕竟它也是会占用一定的资源,所以应该有一个更大值,当超过这个值,系统就会删除最早的连接,这样始终保持在一个数量级。

这个数值就是由net.ipv4.tcp_max_tw_buckets这个参数来决定的。

CentOS7系统,你可以使用sysctl -a |grep tw_buckets来查看它的值,默认为32768,

你可以适当把它调低,比如调整到8000,毕竟这个状态的连接太多也是会消耗资源的。

但你不要把它调到几十、几百这样,因为这种状态的tcp连接也是有用的,

如果同样的客户端再次和服务端通信,就不用再次建立新的连接了,用这个旧的通道,省时省力。

net.ipv4.tcp_tw_recycle = 1

该参数的作用是快速回收timewait状态的连接。上面虽然提到系统会自动删除掉timewait状态的连接,但如果把这样的连接重新利用起来岂不是更好。

所以该参数设置为1就可以让timewait状态的连接快速回收,它需要和下面的参数配合一起使用。

net.ipv4.tcp_tw_reuse = 1

该参数设置为1,将timewait状态的连接重新用于新的TCP连接,要结合上面的参数一起使用。

net.ipv4.tcp_syncookies = 1

tcp三次握手中,客户端向服务端发起syn请求,服务端收到后,也会向客户端发起syn请求同时连带ack确认,

假如客户端发送请求后直接断开和服务端的连接,不接收服务端发起的这个请求,服务端会重试多次,

这个重试的过程会持续一段时间(通常高于30s),当这种状态的连接数量非常大时,服务器会消耗很大的资源,从而造成瘫痪,

正常的连接进不来,这种恶意的半连接行为其实叫做syn flood攻击。

设置为1,是开启SYN Cookies,开启后可以避免发生上述的syn flood攻击。

开启该参数后,服务端接收客户端的ack后,再向客户端发送ack+syn之前会要求client在短时间内回应一个序号,

如果客户端不能提供序号或者提供的序号不对则认为该客户端不合法,于是不会发ack+syn给客户端,更涉及不到重试。

net.ipv4.tcp_max_syn_backlog

该参数定义系统能接受的更大半连接状态的tcp连接数。客户端向服务端发送了syn包,服务端收到后,会记录一下,

该参数决定最多能记录几个这样的连接。在CentOS7,默认是256,当有syn flood攻击时,这个数值太小则很容易导致服务器瘫痪,

实际上此时服务器并没有消耗太多资源(cpu、内存等),所以可以适当调大它,比如调整到30000。

net.ipv4.tcp_syn_retries

该参数适用于客户端,它定义发起syn的更大重试次数,默认为6,建议改为2。

net.ipv4.tcp_synack_retries

该参数适用于服务端,它定义发起syn+ack的更大重试次数,默认为5,建议改为2,可以适当预防syn flood攻击。

net.ipv4.ip_local_port_range

该参数定义端口范围,系统默认保留端口为1024及以下,以上部分为自定义端口。这个参数适用于客户端,

当客户端和服务端建立连接时,比如说访问服务端的80端口,客户端随机开启了一个端口和服务端发起连接,

这个参数定义随机端口的范围。默认为,建议调整为。

net.ipv4.tcp_fin_timeout

tcp连接的状态中,客户端上有一个是FIN-WAIT-2状态,它是状态变迁为timewait前一个状态。

该参数定义不属于任何进程的该连接状态的超时时间,默认值为60,建议调整为6。

net.ipv4.tcp_keepalive_time

tcp连接状态里,有一个是established状态,只有在这个状态下,客户端和服务端才能通信。正常情况下,当通信完毕,

客户端或服务端会告诉对方要关闭连接,此时状态就会变为timewait,如果客户端没有告诉服务端,

并且服务端也没有告诉客户端关闭的话(例如,客户端那边断网了),此时需要该参数来判定。

比如客户端已经断网了,但服务端上本次连接的状态依然是established,服务端为了确认客户端是否断网,

就需要每隔一段时间去发一个探测包去确认一下看看对方是否在线。这个时间就由该参数决定。它的默认值为7200秒,建议设置为30秒。

net.ipv4.tcp_keepalive_intvl

该参数和上面的参数是一起的,服务端在规定时间内发起了探测,查看客户端是否在线,如果客户端并没有确认,

此时服务端还不能认定为对方不在线,而是要尝试多次。该参数定义重新发送探测的时间,即之一次发现对方有问题后,过多久再次发起探测。

默认值为75秒,可以改为3秒。

net.ipv4.tcp_keepalive_probes

第10和第11个参数规定了何时发起探测和探测失败后再过多久再发起探测,但并没有定义一共探测几次才算结束。

该参数定义发起探测的包的数量。默认为9,建议设置2。

设置和范例

在Linux下调整内核参数,可以直接编辑配置文件/etc/sysctl.conf,然后执行sysctl -p命令生效

cat >> /etc/sysctl.conf

# kernel optimization

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_keepalive_time = 600

net.ipv4.ip_local_port_range =

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

EOF # 《Linux就该这么学》

将上面的内核参数加入/etc/sysctl.conf文件中,执行如下命令使之生效:

sysctl -p

关于linux keeplive的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 学会Linux Keeplive,保持网络连接不中断 (linux keeplive)