Not reliable(不可靠)
HTTP是一个无状态协议,这意味着每个请求都是独立的,Keep-Alive没能改变这个结果。另外,Keep-Alive也不能保证客户端和服务器之间的连接一定是活跃的,在HTTP1.1版本中也如此。唯一能保证的就是当连接被关闭时你能得到一个通知,所以不应该让程序依赖于Keep-Alive的保持连接特性,否则会有意想不到的后果
Keep-Alive和POST
在HTTP1.1细则中规定了在一个POST消息体后面不能有任何字符,还指出了对于某一个特定的浏览器可能并不遵循这个标准(比如在POST消息体的后面放置一个CRLF符)。而据我所知,大部分浏览器在POST消息体后都会自动跟一个CRLF符再发送,如何解决这个问题呢?根据上面的说明在POST请求头中禁止使用Keep-Alive,或者由服务器自动忽略这个CRLF,大部分服务器都会自动忽略,但是在未经测试之前是不可能知道一个服务器是否会这样做。
Java实现--客户端
在客户端,Java抽象了Keep-Alive,和程序员分享离开来,HttpURLConnection类自动实现了Keep-Alive,如果程序员没有介入去操作Keep-Alive,Keep-Alive会通过客户端内部的一个HttpURLConnection类的实例对象来自动实现。也就是说,在java中keep-alive是由一个Java类库来实现的,但在其他类库中不一定可用。
Java实现--服务器端
在服务器端,Java依然是将Keep-Alive抽象出来,HttpServlet、HttpServletRequest、和HttpServletResponse类自动实现 了Keep-Alive。这种情况下一些由第三方控制的操作是可能的,如在KeepAliveServlet中提到的JavaWebServer,Keep-Alive是否启用由两个因素决定,内容长度和输出大小,如果内容长度是响应的一部分(即这段内容长度输出后还有内容需要输出),则Keep-Alive被启用(当然需要客户端支持的情况下);如果内容长度未设定,则Servlet会试着计算响应缓冲区长度以确定内容长度,在Javasoft实现中,使用一个4KB的缓冲区(相当于上面说的响应)。也就是说如果内容长度未设定,并且返回数据超过4KB,此时相当于内容长度大于响应长度,而不是响应长度一部分,Keep-Alive就不会被启用 。
转载某论坛的讨论:
keep alive通俗地讲,就是所谓的常连接。常连接节省了TCP连接过程的开销,有一定的优势。现有操作系统越来越先进,建立连接的开销越来越小,比如 linux 2.6的epoll,freebsd的kqueue,可以让程序不fork进程或开线程就能同时服务N多连接。与此同时,客户端比如IE,Firefox 却可以同时开多个线程取内容,如果开了Keep alive,反而不好。因此一般情况下不需Keep Alive
Keep-Alive 持续性连接,在HTTP 中,持续性连接的工作方式是服务器通过响应的Content-Length 首部告诉客户端响应体有多大。客户端能够在下载的过程中准确的显示进度条。
所以Keep-Alive 还是很有必要的。
觉得keepalive就是为长连接准备的,如果长连接设计是合理的,那么这个机制是有必要的,无论是传输层TCP的分节,还是应用层实现的消息。但是的确,TCP(SO_KEEPALIVE选项)提供的心跳跳的是慢点,大概2小时后才连续发几个探测分节。个人接触较多的还属于应用层keepalive一类。
keep-alive的主要目的是为了给服务器提供一个实时向客户端推送信息的手段(比如Gmail的新邮件到达),而不需要不停的通过客户端刷新实现,从这个角度而言,keep-alive对很多应用是必要的,尤其是交互类的。
http的keep-alive是看情况的
如果一个访问会对同一个服务器请求多次那是有用的。不然就是没用的。
比如在完全分离动态页面和静态文件的时候,跑动态页面的服务器就可以关闭keep-alive,以节省连接数。