HTTP是無狀態的 也就是說,瀏覽器和伺服器每進行一次HTTP操作,就建立一次串連,但任務結束就中斷串連。如果用戶端瀏覽器訪問的某個HTML或其他類型的Web頁中包含有其他的Web資源,如JavaScript檔案、影像檔、CSS檔案等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話 HTTP1.1和HTTP1.0相比較而言,最大的區別就是增加了持久串連支援(貌似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態的,或者說是不可以信任的。 如果瀏覽器或者伺服器在其頭資訊加入了這行代碼 Connection:keep-alive TCP串連在發送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的串連發送請求。保持串連節省了為每個請求建立新串連所需的時間,還節約了頻寬。 實現長串連要用戶端和服務端都支援長串連。 如果web伺服器端看到這裡的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1預設進行持久串連),它就可以利用持久串連的優點,當頁麵包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點, web伺服器需要在返回給用戶端HTTP頭資訊中發送一個Content-Length(返回資訊本文的長度)頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然 後在正式寫出內容之前計算它的大小 無論用戶端瀏覽器 (Internet Explorer) 還是 Web 服務器具有較低的 KeepAlive 值,它都將是限制因素。例如,如果用戶端的逾時值是兩分鐘,而 Web 服務器的逾時值是一分鐘,則最大逾時值是一分鐘。用戶端或伺服器都可以是限制因素 在header中加入 --Connection:keep-alive 在HTTp協議請求和響應中加入這條就能維持長串連。 再封裝HTTP訊息資料體的訊息應用就顯的非常簡單易用 Http Keep-Alive seems to be massively misunderstood. Here‘s a short description of how it works, under both1.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 the connection 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 。 用 method.setRequestHeader("Connection" , "Keep-Alive" or "close") 來控制是否保持串連。 常用的apache、resin、tomcat等都有相關的配置是否支援keep-alive。 tomcat中可以設定:maxKeepAliveRequests 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 as HTTP/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串連後不管是否使用都保持串連,但安全性較差, 所謂短串連指建立SOCKET串連後發送後接收完資料後馬上中斷連線,一般銀行都使用短串連 解釋2 長串連就是指在基於tcp的通訊中,一直保持串連,不管當前是否發送或者接收資料。 而短串連就是只有在有資料轉送的時候才進行串連,客戶-伺服器通訊/傳輸資料完畢就關閉串連。 解釋3 長串連和短串連這個概念好像只有移動的CMPP協議中提到了,其他的地方沒有看到過。 通訊方式 各網元之間共有兩種串連方式:長串連和短串連。所謂長串連,指在一個TCP串連上可以連續發送多個資料包,在TCP串連保持期間,如果沒有資料包發送,需要雙方發檢測包以維持此串連。短串連是指通訊雙方有資料互動時,就建立一個TCP串連,資料發送完成後,則斷開此TCP串連,即每次TCP串連只完成一對 CMPP訊息的發送。 現階段,要求ISMG之間必須採用長串連的通訊方式,建議SP與ISMG之間採用長串連的通訊方式。 解釋4 短串連:比如http的,只是串連、請求、關閉,過程時間較短,伺服器若是一段時間內沒有收到請求即可關閉串連。 長串連:有些服務需要長時間串連到伺服器,比如CMPP,一般需要自己做線上維持。
最近在看“伺服器推送技術”,在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(彗星:某人給伺服器推送技術起的名字)的支援,呵呵。 |