天天看點

http無連接配接、無狀态以及解決方案

http協定是超文本傳輸協定,屬于應用層的面向對象的協定,HTTP協定一共有五大特點

1、支援客戶/伺服器模式;

2、簡單快速;

3、靈活;

4、無連接配接;

5、無狀态

下面簡單介紹無連接配接和無狀态

無連接配接:

    無連接配接的含義   是限制每次連接配接隻處理一個請求。伺服器處理完客戶的請求,并收到客戶的應答後,即斷開連接配接。采用這種方式可以節省傳輸時間。随着時間的推移,網頁變得越來越複雜,裡面可能嵌入了很多圖檔,這時候每次通路圖檔都需要建立一次 TCP 連接配接就顯得很低效。後來,Keep-Alive 被提出用來解決這效率低的問題。

  Keep-Alive 功能使用戶端到伺服器端的連接配接持續有效,當出現對伺服器的後繼請求時,Keep-Alive 功能避免了建立或者重建立立連接配接。市場上的大部分 Web 伺服器,包括 iPlanet、IIS 和 Apache,都支援 HTTP Keep-Alive。對于提供靜态内容的網站來說,這個功能通常很有用。但是,對于負擔較重的網站來說,這裡存在另外一個問題:雖然為客戶保留打開的連接配接有一定的好處,但它同樣影響了性能,因為在處理暫停期間,本來可以釋放的資源仍舊被占用。當Web伺服器和應用伺服器在同一台機器上運作時,Keep-Alive 功能對資源利用的影響尤其突出。

  這樣一來,用戶端和伺服器之間的 HTTP 連接配接就會被保持,不會斷開(超過 Keep-Alive 規定的時間,意外斷電等情況除外),當用戶端發送另外一個請求時,就使用這條已經建立的連接配接。

Keep-Alive和POST

      在HTTP1.1細則中規定了在一個POST消息體後面不能有任何字元,還指出了對于某一個特定的浏覽器可能并不遵循這個标準(比如在POST消息體的後面放置一個CRLF符)。而據我所知,大部分浏覽器在POST消息體後都會自動跟一個CRLF符再發送,如何解決這個問題呢?根據上面的說明在POST請求頭中禁止使用Keep-Alive,或者由伺服器自動忽略這個CRLF,大部分伺服器都會自動忽略,但是在未經測試之前是不可能知道一個伺服器是否會這樣做。 

Keep-Alive 在 Java實作--用戶端

      在用戶端,Java抽象了Keep-Alive,和程式員分享離開來,HttpURLConnection類自動實作了Keep-Alive,如果程式員沒有介入去操作Keep-Alive,Keep-Alive會通過用戶端内部的一個HttpURLConnection類的執行個體對象來自動實作。也就是說,在java中keep-alive是由一個Java類庫來實作的,但在其他類庫中不一定可用。

Keep-Alive 在Java實作--伺服器端

       在伺服器端,Java依然是将Keep-Alive抽象出來,HttpServlet、HttpServletRequest、和HttpServletResponse類自動實作 了Keep-Alive。這種情況下一些由第三方控制的操作是可能的,如在KeepAliveServlet中提到的JavaWebServer,Keep-Alive是否啟用由兩個因素決定,内容長度和輸出大小,如果内容長度是響應的一部分(即這段内容長度輸出後還有内容需要輸出),則Keep-Alive被啟用(當然需要用戶端支援的情況下);如果内容長度未設定,則Servlet會試着計算響應緩沖區長度以确定内容長度,在Javasoft實作中,使用一個4KB的緩沖區(相當于上面說的響應)。也就是說如果内容長度未設定,并且傳回資料超過4KB,此時相當于内容長度大于響應長度,而不是響應長度一部分,Keep-Alive就不會被啟用

無狀态:

    用戶端浏覽器向HTTP伺服器發送請求,繼而HTTP伺服器将相應的資源發回給用戶端這樣一個過程中,無論對于用戶端還是伺服器,都沒有必要記錄這個過程,因為每一次請求和響應都是相對獨立的,就好像你在自動售貨機前投下硬币購買商品一樣,誰都不會也不需要記住這樣一個交易過程。即  協定對于事務處理沒有記憶能力。缺少狀态意味着如果後續處理需要前面的資訊,則它必須重傳,這樣可能導緻每次連接配接傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

HTTP 協定這種特性有優點也有缺點,優點在于解放了伺服器,每一次請求“點到為止”不會造成不必要連接配接占用,缺點在于每次請求會傳輸大量重複的内容資訊。

  用戶端與伺服器進行動态互動的 Web 應用程式出現之後,HTTP 無狀态的特性嚴重阻礙了這些應用程式的實作,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。于是,兩種用于保持 HTTP 連接配接狀态的技術就應運而生了,一個是 Cookie,而另一個則是 Session。

  Cookie可以保持登入資訊到使用者下次與伺服器的會話,換句話說,下次通路同一網站時,使用者會發現不必輸入使用者名和密碼就已經登入了(當然,不排除使用者手工删除Cookie)。而還有一些Cookie在使用者退出會話的時候就被删除了,這樣可以有效保護個人隐私。

  Cookies 最典型的應用是判定注冊使用者是否已經登入網站,使用者可能會得到提示,是否在下一次進入此網站時保留使用者資訊以便簡化登入手續,這些都是 Cookies 的功用。另一個重要應用場合是“購物車”之類處理。使用者可能會在一段時間内在同一家網站的不同頁面中選擇不同的商品,這些資訊都會寫入 Cookies,以便在最後付款時提取資訊。

       與Cookie 相對的一個解決方案是 Session,它是通過伺服器來保持狀态的。

  當用戶端通路伺服器時,伺服器根據需求設定 Session,将會話資訊儲存在伺服器上,同時将标示 Session 的 SessionId 傳遞給用戶端浏覽器,浏覽器将這個 SessionId 儲存在記憶體中,我們稱之為無過期時間的 Cookie。浏覽器關閉後,這個 Cookie 就會被清掉,它不會存在于使用者的 Cookie 臨時檔案。

  以後浏覽器每次請求都會額外加上這個參數值,伺服器會根據這個 SessionId,就能取得用戶端的資料資訊。

  如果用戶端浏覽器意外關閉,伺服器儲存的 Session 資料不是立即釋放,此時資料還會存在,隻要我們知道那個 SessionId,就可以繼續通過請求獲得此 Session 的資訊。