TCP Keepalivephp
Tcp keepalive的起源
双方创建交互的链接,可是并非一直存在数据交互,有些链接会在数据交互完毕后,主动释放链接,而有些不会,那么在长时间无数据交互的时间段内,
交互双方都有可能出现掉电、死机、异常重启等各类意外,当这些意外发生以后,这些TCP链接并将来得及正常释放,那么,链接的另外一方并不知道对端的状况,
它会一直维护这个链接,长时间的积累会致使很是多的半打开链接,形成端系统资源的消耗和浪费,为了解决这个问题,在传输层能够利用TCP的保活报文来实现。nginx
Tcp Keepalive存在的做用数据库
1.探测链接的对端是否存活
在应用交互的过程当中,可能存在如下几种状况:
(1)客户端或服务器意外断电,死机,崩溃,重启。
(2)中间网络已经中断,而客户端与服务器并不知道。浏览器
利用保活探测功能,能够探知这种对端的意外状况,从而保证在乎外发生时,能够释放半打开的TCP链接。服务器
2.防止中间设备因超时删除链接相关的链接表
中间设备如防火墙等,会为通过它的数据报文创建相关的链接信息表,并为其设置一个超时时间的定时器,若是超出预约时间,某链接无任何报文交互的话,
中间设备会将该链接信息从表中删除,在删除后,再有应用报文过来时,中间设备将丢弃该报文,从而致使应用出现异常,这个交互的过程大体以下图所示:网络
这种状况在有防火墙的应用环境下很是常见,这会给某些长时间无数据交互可是又要长时间维持链接的应用(如数据库)带来很大的影响,为了解决这个问题,
应用自己或TCP能够经过保活报文来维持中间设备中该链接的信息,(也能够在中间设备上开启长链接属性或调高链接表的释放时间来解决,
可是,这个影响可能较大,有机会再针对这个作详细的描述,在此很少说)。socket
常见应用故障场景:tcp
某财务应用,在客户端须要填写大量的表单数据,在客户端与服务器端创建TCP链接后,客户端终端使用者将花费几分钟甚至几十分钟填写表单相关信息,
终端使用者终于填好表单所需信息后,点击“提交”按钮,结果,这个时候因为中间设备早已经将这个TCP链接从链接表中删除了,
其将直接丢弃这个报文或者给客户端发送RST报文,应用故障产生,这将致使客户端终端使用者全部的工做将须要从新来过,给使用者带来极大的不便和损失。 性能
TCP保活报文交互过程 spa
TCP保活可能带来的问题
1.中间设备因大量保活链接,致使其链接表满
网关设备因为保活问题,致使其链接表满,没法新建链接(XX局网闸故障案例)或性能降低严重
2.正常链接被释放
当链接一端在发送保活探测报文时,中间网络正好因为各类异常(如链路中断、中间设备重启等)而没法将该保活探测报文正确转发至对端时,
可能会致使探测的一方释放原本正常的链接,可是这种可能状况发生的几率较小,另外,通常也能够增长保活探测报文发生的次数来减少这种状况发生的几率和影响。
HTTP Keepalive
Httpd守护进程,通常都提供了keep-alive timeout时间设置参数。好比nginx的keepalive_timeout,和Apache的KeepAliveTimeout。
这个 keepalive_timout时间值意味着:一个http产生的tcp链接在传送完最后一个响应后,还须要hold住 keepalive_timeout秒后,才开始关闭这个链接。
当httpd守护进程发送完一个响应后,理应立刻主动关闭相应的tcp链接,设置 keepalive_timeout后,httpd守护进程会想说:”再等等吧,看看浏览器还有没有请求过来”,
这一等,即是 keepalive_timeout时间。若是守护进程在这个等待的时间里,一直没有收到浏览器发过来http请求,则关闭这个http链接。
1.在没有设置 keepalive_timeout状况下,一个socket资源从创建到真正释放须要通过的时间是:创建tcp链接 + 传送http请求 + php脚本执行 + 传送http响应 + 关闭tcp链接
2.设置了keepalive_timout时间状况下,一个socket创建到释放须要的时间是多了keepalive_timeout时间。
http keep-alive与tcp keep-alive
http keep-alive与tcp keep-alive,不是同一回事,意图不同。http keep-alive是为了让tcp活得更久一点,以便在同一个链接上传送多个http,
提升socket的效率。而tcp keep-alive是TCP的一种检测TCP链接情况的保鲜机制。tcp keep-alive保鲜定时器,支持三个系统内核配置参数:
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 15 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes
keepalive是TCP保鲜定时器,当网络两端创建了TCP链接以后,闲置idle(双方没有任何数据流发送往来)了 tcp_keepalive_time后
服务器内核就会尝试向客户端发送侦测包,来判断TCP链接情况(有可能客户端崩溃、强制关闭了应用、主机不可达等等)。若是没有收到对方的回答(ack包),
则会在 tcp_keepalive_intvl后再次尝试发送侦测包,直到收到对对方的ack,若是一直没有收到对方的ack,一共会尝试 tcp_keepalive_probes次,
每次的间隔时间在这里分别是15s, 30s, 45s, 60s, 75s。若是尝试tcp_keepalive_probes,依然没有收到对方的ack包,则会丢弃该TCP链接。
TCP链接默认闲置时间是2小时,通常设置为30分钟足够了。也就是说,仅当nginx的keepalive_timeout值设置高于tcp_keepalive_time,
而且距此tcp链接传输的最后一个http响应,通过了tcp_keepalive_time时间以后,操做系统才会发送侦测包来决定是否要丢弃这个TCP链接。
通常不会出现这种状况, 除非你须要这样作。
keep-alive与TIME_WAIT 使用http keep-alvie,能够减小服务端TIME_WAIT数量(由于由服务端httpd守护进程主动关闭链接)。道理很简单,相较而言,启用keep-alive, 创建的tcp链接更少了,天然要被关闭的tcp链接也相应更少了。