HTTP協議無狀態中的 "狀態" 到底指的是什麼?

2021-02-13 架構師
引子

最近在好好了解http,發現對介紹http的第一句話【http協議是無狀態的,無連接的】就無法理解了:無狀態的【狀態】到底指的是什麼?!

找了很多資料不僅沒有發現有一針見血正面回答這個問題的,而且有些解釋還充斥了各種錯誤,看著看著就覺得心裡憋著一股濁氣吐不出來

於是在看了很多資料之後,我一口吐出濁氣,大聲正面提出這個問題:http協議無狀態中的【狀態】到底指的是什麼?!

然後開始不斷探索解決這個問題。。。

最終很高興的是我找到了讓人滿意的答案,先賣個關子,各位如果著急可以直接拉到最下查看

正文

http協議無狀態中的【狀態】到底指的是什麼?!

1.先來看這句話的另外兩個概念:(標準的http協議是無狀態的,無連接的) 標準的http協議指的是不包括cookies, session,application的http協議,他們都不屬於標準協議,雖然各種網絡應用提供商,實現語言、web容器等,都默認支持它

2.無連接指的是什麼

每一個訪問都是無連接,伺服器挨個處理訪問隊列裡的訪問,處理完一個就關閉連接,這事兒就完了,然後處理下一個新的無連接的含義是限制每次連接只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連接

對於【無狀態】,我看到很多隔著一層磨砂玻璃一樣的模糊說法(官方或者教程裡的說法),看著非常難受(但其實算是對的)(後來我發現我為什麼覺得它看著難受了,因為他們引入了很多新的,而且明顯是一個可能用在很多地方的廣義名詞,這些詞最大的作用就是,混淆概念,下面我標註了)

協議對於事務處理沒有記憶能力【事物處理】【記憶能力】每次的請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求是無直接關係的,它不會受前面的請求應答情況直接影響,也不會直接影響後面的請求應答情況【無直接聯繫】【受直接影響】伺服器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求伺服器【狀態】

我必須得到確切而具體的解釋!

這幾點給了我下一步思考的方向:

1.【伺服器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求伺服器 】這裡的客戶端的狀態是不是確切地指伺服器沒有保存客戶的信息呢?但顯然不是啊

2.【HTTP無狀態的特性嚴重阻礙了這些應用程式的實現,畢竟交互是需要承前啟後的,簡單的購物車程序也要知道用戶到底在之前選擇了什麼商品】我對此質疑為什麼無狀態就不能實現購物車呢?伺服器就不能存儲東西了麼?

3.【 每次的請求都是獨立的,<它的執行情況和結果>與<前面的請求>和<之後的請求>是無直接關係的】我覺得這個說法比較靠譜,但是所謂的不同請求間的沒有關係,是指的請求內容沒有關係,還是只是指請求本身沒有關係?

請求內容沒有關係只可能是伺服器上不存有用戶數據才可能啊,但是顯然是存有的啊請求本身沒有關係,這又有什麼意義呢,每一次的請求有什麼價值?

根據這個方向我做了一個模擬訪問實驗:假如沒有cookie沒有session,只有http的時候,那當一個註冊用戶訪問這個購物網站的時候,會發生這些事情:

1.前提情況:

伺服器肯定為每個註冊用戶建立了數據表,記錄用戶的數據

2.第一步需要登錄

用戶通過http把用戶的用戶名和密碼發送給伺服器,伺服器把他們跟自己存有的用戶資料對比,如果一致,則返回信息登錄成功

3.然後用戶點擊某一商品頁

而雖然http能傳送用戶名和密碼,而且剛才也輸入了,還驗證成功了,但是因為伺服器既不會記得你登錄的狀態,你的客戶端也不會存儲你剛才輸入的用戶名和密碼所以因為這一次訪問因為無法確定你的身份,只能訪問失敗這時候如果要解決這個問題,而且沒有cookie沒有session,那就只能你在訪問網址的同時繼續帶上你的用戶名和密碼(繼續輸入咯)其實就像我現在的APP一樣

4.假設上一步的問題解決了,就是每次訪問的時候都會手動輸入用戶名和密碼,然後現在的情況是:你已經選了幾件商品在你的購物車中,你想再添加一件商品,於是你點擊某個商品旁邊的加號

這個動作也相當於輸入一個網址,網址的內容是發送一個請求,往你的購物車中加入這個商品系統首先用你傳來的用戶名和密碼驗證你的身份,然後訪問你的資料庫,在其中的購物車屬性下加一條數據,就是這個商品的數據

5.OK,實驗結束,看似沒有cookie沒有session也能湊合解決問題,其實兩個操作都有很大的問題

你每訪問一次需要權限的內容都需要在客戶端輸入用戶名和密碼,這一項的繁瑣就不必贅述了多次少量的訪問存在非常大的性能浪費。非常容易就能想到肯定是一次大量的操作更加有效率,於是就想到了緩存區你的非重要瑣碎數據也被寫進資料庫中,跟你的主要數據放在一起一次次添加和刪除購物車其實只是跟你這次瀏覽,或者叫這次會話有關,是臨時的數據,跟用戶的主要信息無關,它們沒什麼價值,純粹的冗餘數據(不排除現在有的公司覺得這種數據也有非常大的價值可以讓它們巧妙的利用),用什麼存放這些臨時的數據,我們也很容易想到緩存區

經過這個模擬訪問實驗,結合前面的思考方向,我們知道了三點:

伺服器上肯定存有用戶的數據,你提交的增刪改查它也能夠處理,所以這句話中【伺服器中沒有保存客戶端的狀態】的狀態並不是指用戶的數據,我們的猜測不對我們的質疑對了,無狀態能實現購物車,可以通過伺服器上存有的用戶數據來實現但是,使用上面這種方式實現購物車,存在三個比較大的問題。由此,我們不禁會想,這三個問題的解決是不是跟我們不確切了解的【狀態】一詞有關?於是,接下來我們來通過解決這三個問題來把【狀態】的意義探尋下去

由上所述,我們可以在http的基礎上增加一些機制來解決上面出現的三個問題

1.在用戶端增加一個記錄本是非常有必要的,正好官方加入的cookie機制跟這個一樣,它的用處也確實是上面討論的那樣,一般就是用來標識訪問者的身份

2.在伺服器增加一個緩存區能同時解決後兩個問題

有了這個緩存區作為一個數據緩衝,就不用一次次地訪問資料庫,浪費大量計算機資源,而是在最後統一歸入資料庫有了這個緩存區,你就不用把臨時的數據放到資料庫中了,只需要在你們交流告一段落之後,再把數據整理,把有用的數據歸入資料庫

3.這裡就自然引申出了一個重要的概念:會話,它作為一個緩衝存儲區被從資料庫中分離出來,理由並不生硬,它有其獨特的重要且不可替代的作用。這個東西恰好跟官方加入的session機制一樣

3.1.另外說一個非常具有迷惑性的容易讓人對session的主要作用產生偏離的理解:認為session存在的價值就是給訪問者分配一個sessionID代替用戶名和密碼,

3.2.為什麼非常具有迷惑性,因為session確實做了這件事,而且也起到了很大的作用,所以它是對的,但是只對一半,而且沒有涉及問題的本質,這種情況是最危險的(看似很有說服力,把你說服了,所以你很難有動力繼續找下去,但是真實情況跟它有偏差,但是偏差不大,所以又很難把你說服回來,只有隱隱的不對勁,這個時候你離真實最近,也離真實最遠)

3.3.那就順便說說它為什麼是對的,也就是用session做的另一件有用的事:

給每個session一個ID,一方面用來方便自己查詢,另一方面把這個ID給用戶,用戶下一次訪問的時候就可以不用用戶名和密碼,而是直接使用這個ID來表明自己的身份首先,這個ID安全嗎?這個ID比直接傳用戶名和密碼安全嗎?不嚴格加密的sessionID和用戶名和密碼一樣,都不太安全你很容易會想到,本來用戶名和密碼的組合還特地設置地比較複雜,你這換一組數字就代替了,是不是太不安全了?我們知道http協議本身是完全不加密的,如果使用用戶名和密碼,第一次訪問是放在http頭中,後邊自動保存了密碼就會放在cookie中,這些都完全沒有加密,它的安全性基本為0,就是裸奔了,只要被竊取,那就丟失了所以,就這個意義來講,sessionID的安全性跟使用用戶名和密碼沒什麼區別但是其實,雖然http本身不能加密,但是有些軟體什麼的,能在應用層面手動給你加密,比如QQ就會使用戶名密碼加臨時驗證碼聯合哈希,sessionID加一個時間戳簡單加密也是非常常用的方法而且因為sessionID本身有有效期,即使丟了,也可能很快失效,造成的損失可能沒那麼大,而用戶名跟密碼丟了,那就大了

OK,通過獨立地解決純http機制會產生的問題,我們探討了cookie和session機制的本質。而且想到:【使用http協議,伺服器中不會保存客戶端的狀態】所產生的問題通過增加cookie和session機制解決了,是不是就意味著這個【狀態】跟cookie和session的關係非常緊密?

所以這個無狀態指的是【沒有對 本次會話 設置一個緩存區,記錄這次會話的狀態,緩存區包括伺服器端和用戶端】但好像還是沒有點破關鍵(主要是覺得跟前面那些官方對狀態的說法不太吻合,甚至沒有對應關係)

忽然我想到一個問題:一個有狀態的http是什麼樣的?

1.很難直接想像有狀態的http是什麼樣,因為http這種機制是天然無狀態的

2.那就類比一下吧,另一個天然有狀態的機制叫TCP

如果有狀態的意思是它的每次請求是有聯繫的,那麼有狀態的TCP的樣子是:假如一份數據分了三份TCP包發送,那這個包上面會標明這是第幾個包,會標明這個包跟那幾個包是有聯繫的,有什麼聯繫

3.但好像這個有狀態的TCP跟我們想要的有狀態的HTTP沒有關係,因為即使每次http請求之間互相有聯繫,它也不能解決上面提到的http無狀態的問題

4.誒,等等,好像能類比:

4.1.假如每個http連接都有一個籤名,於是第一次登陸成功之後,伺服器就知道了這個籤名是允許登陸的,于是之後所有同樣籤名的http連接都能登陸,這裡利用了同一個用戶發出的http連接之間的同主人關係,這裡解決了一個保持登錄狀態的問題

4.2.同樣,來嘗試利用這個【每次http請求之間互相有聯繫】來解決上面碰到的那個問題【每一次操作都要與系統底層的資料庫進行交互】,但想了半天確實無法進行下去。往期:一百期面試題匯總

4.3.不過我靈機一動,從另一個角度來想,好像解決了這個問題:

只有【每次http請求之間互相有聯繫】這個條件,無法解決【每一次操作都要與系統底層的資料庫進行交互】因為很明顯,要解決【每一次操作都要與系統底層的資料庫進行交互】就必須在伺服器端開闢一塊緩存區不過如果你思考一下如何實現【每次http請求之間互相有聯繫】,你就會發現,它也需要在伺服器端開闢一塊緩存區所以【在伺服器端開闢一塊緩存區】才是真正的條件,也就是說,它確實等價於【有狀態】而且我也找到了這個【在伺服器端開闢一塊緩存區】的條件跟前面那些官方對狀態的說法對應的點,那就是:通過在伺服器端開闢一塊緩存區,存儲、記憶、共享一些臨時數據,你就可以:協議對於事務處理有記憶能力【事物處理】【記憶能力】每次的請求都是不獨立的,它的執行情況和結果與前面的請求和之後的請求是直接關係的【不獨立】【直接關係】所以,這個狀態,加上前面說的客戶端也有cookie,就是指,客戶端和伺服器在臨時會話中產生的數據!而前面也說道了,使用緩存區保存臨時會話中的數據是多麼重要所以狀態不僅包括不同URL訪問之間的關係,還有對其他URL訪問的數據記錄,還有一些其他的東西,所以更確切地說,狀態應該是【實現了這些東西所憑藉的後面的緩存空間】中的客戶的臨時數據cookie和session應該是完全實現了有狀態這個功能一種常見的對狀態的誤解:有人在解釋HTTP的無狀態時,把它跟有連接對立,說是兩種方式,也就是如果想不無狀態,就必須有連接,但其實不然有連接和無連接以及之後的Keep-Alive都是指TCP連接TCP一直有狀態,HTTP一直無狀態,但是應用為了有狀態,就給HTTP加了cookie和session機制,讓使用http的應用也能有狀態,但http還是無狀態開始TCP是有連接,後來TCP無連接,再後來也就是現在TCP是Keep-Alive,有點像有連接

相關焦點

  • 都說HTTP協議是無狀態的,這裡的「狀態」到底指什麼?
    協議,發現對介紹http的第一句話【http協議是無狀態的,無連接的】很有意思:這裡的無狀態的【狀態】到底指的是什麼?!於是在看了很多資料之後,大聲正面提出這個問題:http協議無狀態中的【狀態】到底指的是什麼?!然後開始不斷探索解決這個問題。。。最終很高興的是我找到了讓人滿意的答案,先賣個關子,各位如果著急可以直接拉到最下查看。
  • "中軸"和"斜軸"
    "立身中正"是太極拳行拳走架的基本要求。移動時"上領下垂"謂之不偏;轉動時"保有中軸"即為中正。"軸"乃圓轉之中位,但並非一定是垂直方向。事實上人體運動時有兩個重要的軸:一為"中軸",一為"斜軸"。" 中軸"或稱"豎軸"由"百匯穴"至"會陰穴",垂直上下,是人體的衝脈的位置。
  • "骨力"和"結構勁"的不同
    武術界開口多談「勁",而鄙視」力",更推崇整體結構勁,即"整勁",很少有談到提升單個骨頭的力量。但"骨力"是最基本的不可或缺的攻防要素,不應被忽視。 所謂的"骨力"並不是指骨密度有多高,含鈣量多大,骨頭多麼耐衝擊,而是指在正確的操作下能使單個骨頭產生出力量來。初學者與人較勁時往往會有"使不上勁"的感覺,蓋因為不會用"骨力"的緣故。
  • "蓄勁如張弓"一一談談"弓"的形成和運行條件
    上下之弓應指身體之弓,四旁之弓是指"兩臂弓"和"兩腿弓",今天我們先就"兩臂弓"和"兩腿弓"做點深入討論。再有可能涉及到的名詞就是"箭"了。"弓箭弓箭,張弓搭箭,箭射遠方"這是人們思維中的定式。其實"弓體"本身就有它的作用在。在"兩臂弓""兩腿弓"裡,"弦"是虛設的,"箭"是不需要的。先來說一個"臂弓"的形成。只有當你滿足了"腕關節"與"肩關節"之間相吸相系,動態等壓的狀況下,(建立意念之弦)這隻"臂弓"才能成立。一旦"臂弓"成立的狀態下有哪些益處呢?
  • "骨力"與"結構勁"訓練之一:手臂分解
    "骨力"是單根骨頭的能量使用,也可以是一組細小複雜骨頭的聯動使用,比如手或腳,不太容易或沒有必要過份細分。就以一組骨頭看成單個骨頭使用。多根骨頭的組合使用其實就是"結構勁"了。結構組合有大有小,而單根骨頭必然是"結構"的基本原素,值得我們對重要和常用的骨節先行探討清楚。 大臂是整個手臂的根節部位,肱骨粗壯有力,一端通過肩關節與身軀相連,理論上可以輕鬆旋轉360度。
  • 太極拳技巧探秘:之開篇語,談一談太極拳的"道"與"術"
    先來捋一捋"道"與術的關係。古人說「一陰一陽謂之道「,而"陰陰"和合就成了"太極"。所以說:太極,道也!「道」,可理解為真理、規律、本原;「術」是什麼呢?是方法、手段、技藝。太極拳是武術的一種,如果你認可的話,太極拳必然有其獨特的"方法、手段和技藝"。這就是說:太極拳有"道",與"術"兩個元素,二者皆有了無限的探求空間。
  • "襠走下弧"還是"襠走後弧"?
    一一 "結構勁"基礎:"骨力"訓練之三(胯部運動) 胯部運動一向為拳家重視。一是因為胯關節為人體之最大關節,動力渾厚。其二在於腰胯組成了人體的中心部位。於"動態平衡"至關重要。 先談關於"開胯"的問題。有兩種說法:"開前胯"與"開後胯」。沒有人明確聲稱要"開前胯"但大多數人實際上做得就是打開前胯加上斂臀,尾閭拚命向前抵撐。
  • 寄語"拳走低架"的朋友,"功夫"與"膝蓋"能兩全乎?
    都是大男人也不覺得有什麼唐突,我還半開玩笑地調侃了一句:"老師的大腿好粗呵!大師微笑著回答了一句:"功夫都在這倆大腿上呢!"這個畫面在我的腦海裡縈繞了好多年。當時我的解讀是:要想練出下盤功夫,必須得練出粗壯的大腿。所以拳走低架就成了刻意的的追求。注意這是我當時的理解,大師並沒有這樣說噢。
  • 練功,為何要懂得"服食"
    先天陰陽是"清氣上升,積陽為天",這是乾卦;"濁氣下降,積陰為地",這是坤卦。先天陰陽在動蕩之中。這個動蕩是什麼,在下次課中會講到。這個是修行之中的關鍵問題。那麼這個先天陰陽也會相交,那麼乾坤相交之後,--天上也就有了陰氣,地下也就有了陽氣。此時的天地二氣已經不是純陰純陰了,而是陰中有陽,陽中有陰,這就是後天陰陽了。後天陰陽,就是水火。我們所處在天地,已經是後天陰陽了。
  • 解析一下太極拳的"滲透力"與"滲透能力"
    太極拳技巧探秘之二先來解釋一下"滲透力"和"滲透能力"的不同。一滴水落在大地上,水借自重與勢能,具有"滲透力",而土地因其厚重和有隙,無條件全方位地接納了光顧的水滳,使水滴改變了存在的方式或消失於無形,我們稱其為具有"滲透能力"。人的身體是可以具備類似"滲透能力"的。
  • 太極拳 "腰"與"胯"的關係有必要捋捋清楚
    太極拳技法探秘 之六什麼是腰?肋骨以下,臀部以上稱為腰。什麼是胯,通常人們認為盆骨即為胯。楊吳太極拳強調"腰為主宰",而陳式太極拳認為"胯"為人體最大的關節群,非常強調旋胯、轉胯、調胯的作用,趙堡太極拳甚至強調"以胯代手"。
  • "腰為主宰"是如何實現的?
    一一"結構勁"基礎:"骨力"訓練之四(腰錐運動)腰錐五節為脊錐上最粗壯的錐節,我們在此將五節腰椎看作個一個骨節整體,它自然弧形前弓,也稱腰弓。人體的這一段為中段。水平方向有帶脈環繞,前部儲有大小腸等密實器官,在內氣的支持下,"丹田"這部分甚至可徑得起巨力錘打。後部有兩腎左右懸掛,"兩腎抽扯"是腰錐略微左右運動的特徵。
  • 太極拳"腰為主宰"的內涵探秘
    太極拳技法探秘 之七"主宰"是一個很霸氣的詞彙,有統治、支配的意思。用通俗的話說,主宰者可不是一般的領導或先行者,而是統馭一方的王者,是軍隊的司令官。太極拳論裡說"腰為主宰",賦予了"腰"極其重要的地位。到底"腰"的功能何在,值得如此推崇,讓我們一起來探究一下。先看一下"腰"有哪些基本的功能和特質。人體運動有兩大要素:"轉"和"移"。
  • 來看一看"不用力打人"的真相
    正常人要做到"氣與力合"不容易,因為你首先得要把"氣"練出來。但要做"意與力合"卻再正常不過了。一般人都會,一一不經過大腦引導的肢體運動是不可能做功的。瘋子更會一一意念強烈甚至失控導致手舞足蹈。人們生活中的意念與肢體運動通常呈"同向疊加"狀態,自己也許根本就沒有意識到身體的運動與思想意識有什麼大的關係,但想想每個人都會遇到的特殊狀態。
  • "發勁如放箭"一一敢問箭射何方?
    "顯然,楊澄甫說的是:"內氣"如開弓,敵身是"箭"。這已經不是僅僅訓練自身的問題了,還需要把控好對方,讓"弓"與"箭"搭配完美。這是高水平發人效果的一種描述,我們在不少視頻中看到過,前輩高人的確有這種功夫的。但反過來講,當你的"內氣之弓"尚不完備,不達標時。"發人如放箭"只不過是一個美好的憧景和期望,因此對初學者來說,很難有實際操作性。再看看陳鑫的書中能否找到答案。
  • 宗大師偈頌"穆則瑪"之略釋潤心甘露
    原文稍有不同:"無垢智慧之王妙吉祥,無量悲之大庫觀世音,雪域智者頂嚴仁達瓦,敬於童智雙足之蓮花,祈請護佑求寂如蜂我。"但是,仁達瓦尊者看完後則說,此贊於我有所不適,但於你甚是相符。尊者改成"無緣悲之大庫觀世音,無垢智慧之王妙吉祥,摧伏無餘魔軍秘密主,雪域智者頂嚴宗喀巴,洛桑扎巴足下作啟白。"後獻給宗大師。
  • 最大的陰陽就是天地,陰陽二氣結合的產物即"精氣"
    這就好比自然界中有電,雷電會釋放出巨大的能量。但古時候沒有辦法貯存起來,所以雖然有電這種能量,但是無法利用。到了後來,慢慢研究出電池來,,那樣發電後,可以把電貯存到電池中。這樣,電能就可以慢慢釋放,這樣就能夠為我們所利用了。而精氣,就類似於電池的這種狀態。那麼繼續講精氣。人,生活在天之下,地之上,《內經》中講,人生於"氣交"之中。
  • "立身中正"與"胸腰摺疊"
    一一"結構勁"基礎:"骨力"訓練之五(胸錐運動)胸錐七節,是身軀靈活的部位,卻也是最能體現"立身中正"的部位。雖然"立身中正"的涵意遠不止"豎直胸錐"那麼簡單,但對初學者來講,"立身中正"先要體現在胸錐的豎直,使胸背前後均衡。這樣比較容易建立中軸,有了中軸則左右運轉靈活。且有"立木頂千斤"之效。可以參看一些老拳師的照片,能夠始終保持"立身中正"的拳架給人以極度舒適的感覺。
  • 何為精氣,何為陰陽【"精氣"是陰陽二氣結合】受益!純乾貨!
    當天氣下降,遇到地的陰氣,二者就會結合起來,這種結合起來的狀態就是"精氣"。這就好比自然界中有電,雷電會釋放出巨大的能量。但古時候沒有辦法貯存起來,所以雖然有電這種能量,但是無法利用。到了後來,慢慢研究出電池來,那樣發電後,可以把電貯存到電池中。這樣,電能就可以慢慢釋放,這樣就能夠為我們所利用了。而精氣,就類似於電池的這種狀態。人,生活在天之下,地之上,《內經》中講,人生於"氣交"之中。
  • 我們擁有"自由意志"嗎?
    你昨天中午吃了什麼?今天晚上準備吃些什麼?剛才買了哪幾個號碼的彩票?明天準備又去哪裡?對於類似決定,你認為自己是自由自主作出的嗎?實際上你被騙了。你執行的只是一個幕後操控者的意圖。每一時刻,你的精神思想都是那個幕後操控者強加給你的。這也包括你無助的經歷到的焦慮、抑鬱、疑病症或者強迫症。那麼是誰在背後控制著你?如何"擦除"操控者避免患上心理疾病?真正的"自由意志"又在哪裡?