天天看點

談談HTTP狀态保持

HTTP協定本身是無狀态的,無狀态的意思是浏覽器發起的每個HTTP請求,對于服務端而言都是彼此獨立的,即服務端無法直接通過HTTP協定将使用者的多次HTTP請求聯系在一起。這就好比顧客跟自動售貨機的關系一樣,無論你在一台自動售貨機上購買了多少次商品,自動售貨機都沒法“記住”你,也就是說你每一次在該售貨機上購買商品的時候,自動售貨機都會把你當成一個陌生的顧客來對待。

然而在Web應用的很多場景下需要維護使用者狀态才能正常工作。典型的應用就是購物車。當你在網上商城購買商品的時候,每看到一個喜歡的商品可以把它先加入購物車,然後繼續浏覽其他商品,等浏覽完商品後再進行商品的結算。在這個過程中,你與伺服器的通信是通過多次HTTP請求完成的,浏覽器必須通過某種機制識别出你發出的所有HTTP請求是來自同個計算機的同個浏覽器,或者來自同一個賬戶。否則伺服器就沒辦法将購物車裡的商品跟某個人聯系起來,是以也無法實作購物車功能。這種維持HTTP狀态的機制就是會話機制。

會話機制一般有兩種實作方案,一種是基于Session實作,一種是基于Cookie實作。這兩種方案的本質差別是前者是将使用者狀态資訊儲存在服務端,後者是将使用者狀态資訊儲存在用戶端。那麼什麼又是使用者狀态資訊呢?以前面的購物車為例,狀态資訊就是商品資訊。

一、基于Session實作會話保持

基于Session實作會話保持的原理是:在會話的開始(即用戶端第一次向伺服器發送HTTP請求時),伺服器會将會話狀态儲存起來(一般儲存在本機記憶體,當然也可以儲存在其他存儲系統),然後配置設定一個會話辨別(也叫SessionId)給用戶端,這個會話辨別一般儲存在浏覽Cookie裡,以後每次浏覽器發送HTTP請求的時候,都會帶上這個會話辨別到伺服器,伺服器拿到這個會話辨別之後就可以把之前存儲在服務端的狀态資訊與該會話聯系起來,是以也就實作了會話保持。當然如果遇到浏覽器禁用了Cookie的情況,則可以通過url重寫的方式将會話辨別放在url的參數裡,這樣也可以實作會話保持。

二、基于Cookie實作會話保持

基于Cookie實作會話保持與上述基于Session實作會話保持的最主要差別是前者完全将會話狀态資訊存儲在浏覽器Cookie中,這樣一來每次浏覽器發送HTTP請求的時候都會帶上狀态資訊,是以也就可以實作狀态保持。以上述購物車應用為例,服務端可以将商品資訊加密(也可以不加密,但為了安全性,一般會此對狀态資訊進行加密處理)後儲存在浏覽器的Cookie中,這樣一來服務端就能知道你在浏覽的過程中添加了哪些商品到購物車中了。

三、兩者的優缺點

基于Session的會話保持的優點是具有安全性,因為狀态資訊是儲存在服務端的,缺點是不便于伺服器的水準擴充。大型網站的背景一般都不止一台伺服器,可能幾台甚至上百台,浏覽器發送的HTTP請求一般要先通過負載均衡器才能到達具體的背景伺服器,這就會導緻每次HTTP請求可能落到不同的伺服器上,比如說第一次HTTP請求落到server1上,第二次HTTP請求落到server2上。而Session預設是存儲在伺服器本機記憶體的,當多次請求落到不同的伺服器上時,上述方案就不能實作會話保持了。

基于Cookie的會話保持的優點是伺服器不用儲存狀态資訊,減輕服務端存儲壓力,也便于服務端做水準擴充。缺點是不夠安全,因為狀态資訊是存儲在用戶端的,這意味着不能在會話中儲存機密資料,另一個缺點是每次HTTP請求都需要發送額外的Cookie到服務端,會消耗更多帶寬。

總結

上述基于Session機制實作會話保持的方案中,當服務端有多台伺服器的時候可能無法正常工作,那麼是否有其他措施可以在服務端有多台伺服器的時候基于Session實作會話保持呢?答案是肯定的。由于篇幅所限,在此不詳述,後續會再次探讨這個問題。

如果覺得這篇文章對你有幫助,可以掃描下方二維碼,關注本人公衆号,獲得更多優質文章推送。