昨天看了一篇文章,贴上链接又见KeepAlive_阿里技术保障
由于接受水平有限,看完之后还是有点发蒙。
现在我的理解是这样的:两者是完全不同的概念,只是凑巧名字相同。tcp的keepalive指的是周期性的去检查链接是否有效(working),经过一个时钟周期(keepalive_timeout)之后发送一个空的探测报文来检查;而HTTP的keepalive 表示是否允许在同一次TCP链接中进行多次的HTTP请求,从而减少tcp链接建立和断开造成的开销。我不知道以上这样的理解是不是正确的……
另一个困惑我的问题是,两者都有timeout,HTTP的timeout是什么含义呢?如果两者设置的值不同会造成什么后果?
理解是正确的。
TCP Keepalive
主要为了解决对方(client)不在线,回收(Reclaim)服务器端的TCP连接的内存资源TCB(TCP Control Block)。
但是,如果对方(client)依然在线,即对方依然对服务器发出的探测(Probe)报文ACK,那么服务器需要继续维持该TCP连接,并刷新Timeout至默认2小时的值。
对方不在线可以回收存储资源,对方在线无法回收存储资源!!!
HTTP Keepalive
HTTP 1.0默认一个TCP连接只能服务一次HTTP Request/Response。即服务器在发出自己的Response之后,就立马发送Close TCP 连接的请求,触发Client也发出Close TCP连接的请求。至此,TCP连接双向Closed。
很显然TCP连接的使用效率很低,为何一个TCP连接不能服务多次HTTP Request/Response?
于是,HTTP增加一个Connection Header,如果Client/Server任意一方,明确携带:
Connection:Keep-Alive
用于传输这次HTTP交易的TCP Connection是一个长连接(Persist Connection),可以一直使用,直到用户主动关闭TCP连接为止。
显然,TCP连接的利用率明显提高了,但是这又带来一个新问题。如果Client打开一个HTTP页面,就闲置在那里,也没有关闭页面动作。
这个TCP Connection会一直存活下去。
明明Client已经Idle了,明明这个TCP连接已经不需要了,但是服务器却无法关闭它!
有否两全其美的解决方案,既能有效提高TCP连接的利用率,又可以方便服务器回收TCB资源?
有的。
Keep-Alive: timeout=5, max=10
限制长连接最大使用时长= 5分钟,或者最多10次HTTP交易。
这个timeout不会因为流量而刷新,timeout到了连接就会被服务器关闭。
如果使用次数到达10次,但是timeout还没有超时。无妨,依然会被服务器强制关闭。此时,Client的Request可能已经在路上了,但是依然会被服务器丢弃并Reset。
无论Client是否在线,服务器都可以强制关闭连接,并回收资源!!!
综上
TCP Keepalive 是一种温和的资源回收机制,由TCP来全权负责。需要发探测包,只有对方不在线(休眠、关机、重启等),才可以回收。只要对方可以回复ACk,就无法回收。
HTTP keepalive,是一种激进的资源回收机制,由应用程序全权负责。无需发探测包,无论对方是否在线,都可以强制关闭TCP连接!
最后,HTTP timeout、max服务器可以自由设置的。根据大量HTTP交易统计,设置为10分钟、或者max = 100次是比较合理的!
作者|车小胖谈网络|公众号