HTTP是無狀態的 HTTP1.1和HTTP1.0相比較而言,最大的區別就是增長了持久鏈接支持(貌似最新的 http1.0 能夠顯示的指定 keep-alive),但仍是無狀態的,或者說是不能夠信任的。java 若是瀏覽器或者服務器在其頭信息加入了這行代碼web Connection:keep-aliveajax TCP鏈接在發送後將仍然保持打開狀態,因而,瀏覽器能夠繼續經過相同的鏈接發送請求。保持鏈接節省了爲每一個請求創建新鏈接所需的時間,還節約了帶寬。apache 實現長鏈接要客戶端和服務端都支持長鏈接。promise 若是web服務器端看到這裏的值爲「Keep-Alive」,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久鏈接),它就能夠利用持久鏈接的優勢,當頁面包含多個元素時(例如Applet,圖片),顯著地減小下載所須要的時間。要實現這一點, web服務器須要在返回給客戶端HTTP頭信息中發送一個Content-Length(返回信息正文的長度)頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然 後在正式寫出內容以前計算它的大小瀏覽器 不管客戶端瀏覽器 (Internet Explorer) 仍是 Web 服務器具備較低的 KeepAlive 值,它都將是限制因素。例如,若是客戶端的超時值是兩分鐘,而 Web 服務器的超時值是一分鐘,則最大超時值是一分鐘。客戶端或服務器均可以是限制因素tomcat 在header中加入 --Connection:keep-alive Http Keep-Alive seems to be massively misunderstood. Here's a short description of how it works, under both 1.0 and 1.1服務器 HTTP/1.0Under HTTP 1.0, there is no official specification for how keepalive operates. It was, in essence, tacked on to an existing protocol. If the browser supports keep-alive, it adds an additional header to the request: Connection: Keep-Alive Then, when the server receives this request and generates a response, it also adds a header to the response: Connection: Keep-Alive Following this, the connection is NOT dropped, but is instead kept open. When the client sends another request, it uses the same connection. This will continue until either the client or the server decides that the conversation is over, and one of them drops the connection. HTTP/1.1Under HTTP 1.1, the official keepalive method is different. All connections are kept alive, unless stated otherwise with the following header: Connection: close The Connection: Keep-Alive header no longer has any meaning because of this. Additionally, an optional Keep-Alive: header is described, but is so underspecified as to be meaningless. Avoid it. Not reliableHTTP is a stateless protocol - this means that every request is independent of every other. Keep alive doesn’t change that. Additionally, there is no guarantee that the client or the server will keep the connection open. Even in 1.1, all that is promised is that you will probably get a notice that theconnection is being closed. So keepalive is something you should not write your application to rely upon. KeepAlive and POSTThe HTTP 1.1 spec states that following the body of a POST, there are to be no additional characters. It also states that "certain" browsers may not follow this spec, putting a CRLF after the body of the POST. Mmm-hmm. As near as I can tell, most browsers follow a POSTed body with a CRLF. There are two ways of dealing with this: Disallow keepalive in the context of a POST request, or ignore CRLF on a line by itself. Most servers deal with this in the latter way, but there's no way to know how a server will handle it without testing.
Java應用 client用apache的commons-httpclient來執行method 。
經常使用的apache、resin、tomcat等都有相關的配置是否支持keep-alive。
tomcat中能夠設置:
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well asHTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100. 解釋1 所謂長鏈接指創建SOCKET鏈接後不論是否使用都保持鏈接,但安全性較差,
解釋2 長鏈接就是指在基於tcp的通信中,一直保持鏈接,無論當前是否發送或者接收數據。
解釋3 長鏈接和短鏈接這個概念好像只有移動的CMPP協議中提到了,其餘的地方沒有看到過。
解釋4 短鏈接:好比http的,只是鏈接、請求、關閉,過程時間較短,服務器如果一段時間內沒有收到請求便可關閉鏈接。 最近在看「 服務器推送技術」,在B/S結構中,經過某種magic使得客戶端不須要經過輪詢便可以獲得服務端的最新信息(好比股票價格),這樣能夠節省大量的帶寬。
傳統的輪詢技術對服務器的壓力很大,而且形成帶寬的極大浪費。若是改用ajax輪詢,能夠下降帶寬的負荷(由於服務器返回的不是完整頁面),可是對服務器的壓力並不會有明顯的減小。
而推技術(push)能夠改善這種狀況。但由於
HTTP鏈接的特性(短暫,必須由客戶端發起),使得推技術的實現比較困難,常見的作法是經過延長http鏈接的壽命,來實現push。
接下來天然該討論如何延長
http鏈接的壽命,最簡單的天然是死循環法:
【servlet代碼片斷】
public void doGet(Request req, Response res) {
PrintWriter out = res.getWriter();
……
正常輸出頁面
……
out.flush();
while (true) {
out.print("輸出更新的內容");
out.flush();
Thread.sleep(3000);
}
}
若是使用觀察者模式則能夠進一步提升性能。
可是這種作法的缺點在於客戶端請求了這個servlet後,web服務器會開啓一個線程執行servlet的代碼,而servlet由遲遲不願結束,形成該線程也沒法被釋放。因而乎,一個客戶端一個線程,當客戶端數量增長時,服務器依然會承受很大的負擔。
要從根本上改變這個現象比較複雜,目前的趨勢是從web服務器內部入手,用
nio(JDK 1.4提出的java.nio包)改寫request/response的實現,再利用線程池加強服務器的資源利用率,從而解決這個問題,目前支持這一非J2EE官方技術的服務器有
Glassfish和
Jetty(後者只是據說,沒有用過)。
目前也有一些框架/工具能夠幫助你實現推功能,好比pushlets。不過沒有深刻研究。
這兩天準備學習一下Glassfish中對Comet(彗星:某人給服務器推送技術起的名字)的支持,呵呵。
|
http://www.cnblogs.com/lidabo/p/4585900.html