儿童文学

随手记之TCP Keepalive笔记

  • 作者:本站
  • 时间:2019-08-13
  • 62人已阅读
您现在的位置:首页 > 儿童诗歌 > 文章
简介 零。 前言TCP是无感知的虚拟连接,中间断开两端不会立刻得到通知。 一般在使用长连接的环境下,需要心跳保活机制可以勉强感知其存活。 业务层面有心跳机制,TCP协议也提供了心跳

	随手记之TCP Keepalive笔记

零。 前言TCP是无感知的虚拟连接,中间断开两端不会立刻得到通知。

一般在使用长连接的环境下,需要心跳保活机制可以勉强感知其存活。 业务层面有心跳机制,TCP协议也提供了心跳保活机制。 一。

TCPKeepalive解读长连接的环境下,人们一般使用业务层面或上层应用层协议(诸如MQTT,等)里面定义和使用。 一旦有热数据需要传递,若此时连接已经被中介设备断开,应用程序没有及时感知的话,那么就会导致在一个无效的数据链路层面发送业务数据,结果就是发送失败。 无论是因为客户端意外断电、死机、崩溃、重启,还是中间路由网络无故断开、NAT超时等,服务器端要做到快速感知失败,减少无效链接操作。 1.交互过程2.协议解读下面协议解读,基于。 二。 Tcpkeepalive如何使用以下环境是在Linux服务器上进行。

应用程序若想使用,需要设置SO_KEEPALIVE套接口选项才能够生效。 1.系统内核参数配置发送频率tcp_keepalive_intvl乘以发送次数tcp_keepalive_probes,就得到了从开始探测到放弃探测确定连接断开的时间若设置,服务器在客户端连接空闲的时候,每90秒发送一次保活探测包到客户端,若没有及时收到客户端的TCPKeepaliveACK确认,将继续等待15秒*2=30秒。 总之可以在90s+30s=120秒(两分钟)时间内可检测到连接失效与否。

以下改动,需要写入到/etc/文件:net=net=net=保存退出,然后执行sysctl-p生效。 可通过sysctl-a|grepkeepalive命令检测一下是否已经生效。

针对已经设置SO_KEEPALIVE的套接字,应用程序不用重启,内核直接生效。

/netty服务器如何使用只需要在服务器端一方设置即可,客户端完全不用设置,比如基于netty4服务器程序:ServerBootstrapb=ServerBootstrap();(bossGroup,workerGroup).channel().option(_BACKLOG,).childOption(_KEEPALIVE,).handler(LoggingHandler()).childHandler(ChannelInitializerSocketChannel(){Exception{().addLast(EchoServerHandler());}});ChannelFuturef=(port).sync();().closeFuture().sync();Java程序只能做到设置SO_KEEPALIVE选项,至于TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL等参数配置,只能依赖于sysctl配置,系统进行读取。 语言如何设置下面代码摘取自libkeepalive源码,C语言可以设置更为详细的TCP内核参数。

domain,type,protocol){(*libc_socket)(,,);s,optval;*env;*(**)(libc_socket)=dlsym(RTLD_NEXT,);(dlerror()){errno=EACCES;-;}((s=(*libc_socket)(domain,type,protocol))!=-){((domain==PF_INET)(type==SOCK_STREAM)){(!(env=getenv())||strcasecmp(env,)){optval=;}{optval=;}(!(env=getenv())||strcasecmp(env,)){setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,optval,(optval));}((env=getenv())((optval=atoi(env))=)){setsockopt(s,SOL_TCP,TCP_KEEPCNT,optval,(optval));}((env=getenv())((optval=atoi(env))=)){setsockopt(s,SOL_TCP,TCP_KEEPIDLE,optval,(optval));}((env=getenv())((optval=atoi(env))=)){setsockopt(s,SOL_TCP,TCP_KEEPINTVL,optval,(optval));}}}s;}4.针对已有程序没有硬编码KTTCPEEPALIVE实现完全可以借助于第三方工具,通过LD_PRELOAD方式实现。 比如LD_PRELOAD=/the/path/libkeepalivejava-jar/your/path/yourapp这个工具还有一个比较方便的地方,可以直接在程序运行前指定TCP保活详细参数,可以省去配置的麻烦:LD_PRELOAD=/the/path/=KEEPIDLE=KEEPINTVL=java-jar/your/path/针对较老很久不更新的程序,可以尝试一下嘛。 三。 Linux内核层面对keepalive处理参数和定义ineMAX_TCP_KEEPIDLEineMAX_TCP_KEEPINTVLineMAX_TCP_KEEPCNTineMAX_TCP_SYNCNTineTCP_KEEPIDLEineTCP_KEEPINTVLineTCP_KEEPCNTnet/ipv4/,可以找到对应关系:val=(tp-keepalive_time:sysctl_tcp_keepalive_time)/HZ;;val=(tp-keepalive_intvl:sysctl_tcp_keepalive_intvl)/HZ;;val=tp-keepalive_probes:sysctl_tcp_keepalive_probes;;初始化::(1)err=-;{tp-keepalive_time=;(sock_flag(sk,)!((sk-sk_state)(|))){__u32elapsed=tcp_time_stamp-tp-rcv_tstamp;(tp-keepalive_timeelapsed)elapsed=tp-keepalive_time-elapsed;elapsed=;inet_csk_reset_keepalive_timer(sk,elapsed);}};:(1)err=-;tp-keepalive_intvl=;;:(1)err=-;tp-keepalive_probes=;;这里可以找到大部分处理逻辑,net/ipv4/Tcp_:data){sock*sk=(sock*)data;inet_connection_sock*icsk=inet_csk(sk);tcp_sock*tp=tcp_sk(sk);__u32elapsed;bh_lock_sock(sk);(sock_owned_by_user(sk)){inet_csk_reset_keepalive_timer(sk,HZ/);;}(sk-sk_state==TCP_LISTEN){tcp_synack_timer(sk);;}(sk-sk_state==TCP_FIN_WAIT2sock_flag(sk,SOCK_DEAD)){(tp-linger2=){tmo=tcp_fin_time(sk)-TCP_TIMEWAIT_LEN;(tmo){tcp_time_wait(sk,TCP_FIN_WAIT2,tmo);;}}tcp_send_active_reset(sk,GFP_ATOMIC);death;}(!sock_flag(sk,SOCK_KEEPOPEN)||sk-sk_state==TCP_CLOSE);elapsed=keepalive_time_when(tp);(tp-packets_out||sk-sk_send_head)resched;elapsed=tcp_time_stamp-tp-rcv_tstamp;(elapsed=keepalive_time_when(tp)){((!tp-keepalive_probesicsk-icsk_probes_out=sysctl_tcp_keepalive_probes)||(tp-keepalive_probesicsk-icsk_probes_out=tp-keepalive_probes)){tcp_send_active_reset(sk,GFP_ATOMIC);tcp_write_err(sk);;}(tcp_write_wakeup(sk)=){icsk-icsk_probes_out++;elapsed=keepalive_intvl_when(tp);}{elapsed=TCP_RESOURCE_PROBE_INTERVAL;}}{elapsed=keepalive_time_when(tp)-elapsed;}TCP_CHECK_TIMER(sk);sk_stream_mem_reclaim(sk);resched:inet_csk_reset_keepalive_timer(sk,elapsed);;death:tcp_done(sk);:bh_unlock_sock(sk);sock_put(sk);}keepalive_intvl_when函数定义:inlinetcp_sock*tp){tp-keepalive_intvl:sysctl_tcp_keepalive_intvl;}四。

TCPKeepalive引发的错误启用TCPKeepalive的应用程序,一般可以捕获到下面几种类型错误。

Top