自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

難住了N個(gè)面試者,http協(xié)議無狀態(tài)中的 "狀態(tài)" 到底指的是什么?!

數(shù)據(jù)庫 其他數(shù)據(jù)庫
最近在好好了解http,發(fā)現(xiàn)對介紹http的第一句話【http協(xié)議是無狀態(tài)的,無連接的】就無法理解了:無狀態(tài)的【狀態(tài)】到底指的是什么?!來看看吧。

[[337168]]

引子

最近在好好了解http,發(fā)現(xiàn)對介紹http的第一句話【http協(xié)議是無狀態(tài)的,無連接的】就無法理解了:無狀態(tài)的【狀態(tài)】到底指的是什么?!

找了很多資料不僅沒有發(fā)現(xiàn)有一針見血正面回答這個(gè)問題的,而且有些解釋還充斥了各種錯(cuò)誤,看著看著就覺得心里憋著一股濁氣吐不出來

于是在看了很多資料之后,我一口吐出濁氣,大聲正面提出這個(gè)問題:http協(xié)議無狀態(tài)中的【狀態(tài)】到底指的是什么?!

然后開始不斷探索解決這個(gè)問題。。。

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

正文

http協(xié)議無狀態(tài)中的【狀態(tài)】到底指的是什么?!

1.先來看這句話的另外兩個(gè)概念:(標(biāo)準(zhǔn)的http協(xié)議是無狀態(tài)的,無連接的) 標(biāo)準(zhǔn)的http協(xié)議指的是不包括cookies, session,application的http協(xié)議,他們都不屬于標(biāo)準(zhǔn)協(xié)議,雖然各種網(wǎng)絡(luò)應(yīng)用提供商,實(shí)現(xiàn)語言、web容器等,都默認(rèn)支持它

2.無連接指的是什么

  •  每一個(gè)訪問都是無連接,服務(wù)器挨個(gè)處理訪問隊(duì)列里的訪問,處理完一個(gè)就關(guān)閉連接,這事兒就完了,然后處理下一個(gè)新的
  •  無連接的含義是限制每次連接只處理一個(gè)請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接

對于【無狀態(tài)】,我看到很多隔著一層磨砂玻璃一樣的模糊說法(官方或者教程里的說法),看著非常難受(但其實(shí)算是對的)(后來我發(fā)現(xiàn)我為什么覺得它看著難受了,因?yàn)樗麄円肓撕芏嘈碌?,而且明顯是一個(gè)可能用在很多地方的廣義名詞,這些詞最大的作用就是,混淆概念,下面我標(biāo)注了)

  •  協(xié)議對于事務(wù)處理沒有記憶能力【事物處理】【記憶能力】
  •  對同一個(gè)url請求沒有上下文關(guān)系【上下文關(guān)系】
  •  每次的請求都是獨(dú)立的,它的執(zhí)行情況和結(jié)果與前面的請求和之后的請求是無直接關(guān)系的,它不會受前面的請求應(yīng)答情況直接影響,也不會直接影響后面的請求應(yīng)答情況【無直接聯(lián)系】【受直接影響】
  •  服務(wù)器中沒有保存客戶端的狀態(tài),客戶端必須每次帶上自己的狀態(tài)去請求服務(wù)器【狀態(tài)】

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

這幾點(diǎn)給了我下一步思考的方向:

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

2.【HTTP無狀態(tài)的特性嚴(yán)重阻礙了這些應(yīng)用程序的實(shí)現(xiàn),畢竟交互是需要承前啟后的,簡單的購物車程序也要知道用戶到底在之前選擇了什么商品】我對此質(zhì)疑為什么無狀態(tài)就不能實(shí)現(xiàn)購物車呢?服務(wù)器就不能存儲東西了么?

3.【 每次的請求都是獨(dú)立的,<它的執(zhí)行情況和結(jié)果>與<前面的請求>和<之后的請求>是無直接關(guān)系的】我覺得這個(gè)說法比較靠譜,但是所謂的不同請求間的沒有關(guān)系,是指的請求內(nèi)容沒有關(guān)系,還是只是指請求本身沒有關(guān)系?

  •  請求內(nèi)容沒有關(guān)系只可能是服務(wù)器上不存有用戶數(shù)據(jù)才可能啊,但是顯然是存有的啊
  •  請求本身沒有關(guān)系,這又有什么意義呢,每一次的請求有什么價(jià)值?

根據(jù)這個(gè)方向我做了一個(gè)模擬訪問實(shí)驗(yàn):假如沒有cookie沒有session,只有http的時(shí)候,那當(dāng)一個(gè)注冊用戶訪問這個(gè)購物網(wǎng)站的時(shí)候,會發(fā)生這些事情:

1.前提情況:

  •  服務(wù)器肯定為每個(gè)注冊用戶建立了數(shù)據(jù)表,記錄用戶的數(shù)據(jù)
  •  http是無連接的

2.第一步需要登錄

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

3.然后用戶點(diǎn)擊某一商品頁

  •  這個(gè)動作相當(dāng)于輸入一個(gè)商品頁的網(wǎng)址
  •  假如商品頁比較機(jī)密不對外公開,需要是用戶才能訪問
  •  而雖然http能傳送用戶名和密碼,而且剛才也輸入了,還驗(yàn)證成功了,但是因?yàn)榉?wù)器既不會記得你登錄的狀態(tài),你的客戶端也不會存儲你剛才輸入的用戶名和密碼
  •  所以因?yàn)檫@一次訪問因?yàn)闊o法確定你的身份,只能訪問失敗
    •  這時(shí)候如果要解決這個(gè)問題,而且沒有cookie沒有session,那就只能你在訪問網(wǎng)址的同時(shí)繼續(xù)帶上你的用戶名和密碼(繼續(xù)輸入咯)其實(shí)就像我現(xiàn)在的APP一樣

4.假設(shè)上一步的問題解決了,就是每次訪問的時(shí)候都會手動輸入用戶名和密碼,然后現(xiàn)在的情況是:你已經(jīng)選了幾件商品在你的購物車中,你想再添加一件商品,于是你點(diǎn)擊某個(gè)商品旁邊的加號

  •  這個(gè)動作也相當(dāng)于輸入一個(gè)網(wǎng)址,網(wǎng)址的內(nèi)容是發(fā)送一個(gè)請求,往你的購物車中加入這個(gè)商品
  •  系統(tǒng)首先用你傳來的用戶名和密碼驗(yàn)證你的身份,然后訪問你的數(shù)據(jù)庫,在其中的購物車屬性下加一條數(shù)據(jù),就是這個(gè)商品的數(shù)據(jù)
  •  操作結(jié)束后,返回操作成功,并結(jié)束訪問

5.OK,實(shí)驗(yàn)結(jié)束,看似沒有cookie沒有session也能湊合解決問題,其實(shí)兩個(gè)操作都有很大的問題

  •  你每訪問一次需要權(quán)限的內(nèi)容都需要在客戶端輸入用戶名和密碼,這一項(xiàng)的繁瑣就不必贅述了
  •  你的每一次操作都要與系統(tǒng)底層的數(shù)據(jù)庫進(jìn)行交互
    •  多次少量的訪問存在非常大的性能浪費(fèi)。非常容易就能想到肯定是一次大量的操作更加有效率,于是就想到了緩存區(qū)
  •  你的非重要瑣碎數(shù)據(jù)也被寫進(jìn)數(shù)據(jù)庫中,跟你的主要數(shù)據(jù)放在一起
    •  一次次添加和刪除購物車其實(shí)只是跟你這次瀏覽,或者叫這次會話有關(guān),是臨時(shí)的數(shù)據(jù),跟用戶的主要信息無關(guān),它們沒什么價(jià)值,純粹的冗余數(shù)據(jù)(不排除現(xiàn)在有的公司覺得這種數(shù)據(jù)也有非常大的價(jià)值可以讓它們巧妙的利用),用什么存放這些臨時(shí)的數(shù)據(jù),我們也很容易想到緩存區(qū)

搜索Java知音公眾號,回復(fù)“后端面試”,送你一份Java面試題寶典

經(jīng)過這個(gè)模擬訪問實(shí)驗(yàn),結(jié)合前面的思考方向,我們知道了三點(diǎn):

  •  服務(wù)器上肯定存有用戶的數(shù)據(jù),你提交的增刪改查它也能夠處理,所以這句話中【服務(wù)器中沒有保存客戶端的狀態(tài)】的狀態(tài)并不是指用戶的數(shù)據(jù),我們的猜測不對
  •  我們的質(zhì)疑對了,無狀態(tài)能實(shí)現(xiàn)購物車,可以通過服務(wù)器上存有的用戶數(shù)據(jù)來實(shí)現(xiàn)
  •  但是,使用上面這種方式實(shí)現(xiàn)購物車,存在三個(gè)比較大的問題。由此,我們不禁會想,這三個(gè)問題的解決是不是跟我們不確切了解的【狀態(tài)】一詞有關(guān)?于是,接下來我們來通過解決這三個(gè)問題來把【狀態(tài)】的意義探尋下去

由上所述,我們可以在http的基礎(chǔ)上增加一些機(jī)制來解決上面出現(xiàn)的三個(gè)問題

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

2.在服務(wù)器增加一個(gè)緩存區(qū)能同時(shí)解決后兩個(gè)問題

  •  有了這個(gè)緩存區(qū)作為一個(gè)數(shù)據(jù)緩沖,就不用一次次地訪問數(shù)據(jù)庫,浪費(fèi)大量計(jì)算機(jī)資源,而是在最后統(tǒng)一歸入數(shù)據(jù)庫
  •  有了這個(gè)緩存區(qū),你就不用把臨時(shí)的數(shù)據(jù)放到數(shù)據(jù)庫中了,只需要在你們交流告一段落之后,再把數(shù)據(jù)整理,把有用的數(shù)據(jù)歸入數(shù)據(jù)庫

3.這里就自然引申出了一個(gè)重要的概念:會話,它作為一個(gè)緩沖存儲區(qū)被從數(shù)據(jù)庫中分離出來,理由并不生硬,它有其獨(dú)特的重要且不可替代的作用。這個(gè)東西恰好跟官方加入的session機(jī)制一樣

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

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

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

  •  給每個(gè)session一個(gè)ID,一方面用來方便自己查詢,另一方面把這個(gè)ID給用戶,用戶下一次訪問的時(shí)候就可以不用用戶名和密碼,而是直接使用這個(gè)ID來表明自己的身份
  •  首先,這個(gè)ID安全嗎?這個(gè)ID比直接傳用戶名和密碼安全嗎?
    •  不嚴(yán)格加密的sessionID和用戶名和密碼一樣,都不太安全
    •  但是相比較來說,sessionID要安全一些
    •  而使用https是完全安全的

                1.  你很容易會想到,本來用戶名和密碼的組合還特地設(shè)置地比較復(fù)雜,你這換一組數(shù)字就代替了,是不是太不安全了?

                2.  我們知道http協(xié)議本身是完全不加密的,如果使用用戶名和密碼,第一次訪問是放在http頭中,后邊自動保存了密碼就會放在cookie中,這些都完全沒有加密,它的安全性基本為0,就是裸奔了,只要被竊取,那就丟失了

                3.  所以,就這個(gè)意義來講,sessionID的安全性跟使用用戶名和密碼沒什么區(qū)別

                4.  但是其實(shí),雖然http本身不能加密,但是有些軟件什么的,能在應(yīng)用層面手動給你加密,比如QQ就會使用戶名密碼加臨時(shí)驗(yàn)證碼聯(lián)合哈希,sessionID加一個(gè)時(shí)間戳簡單加密也是非常常用的方法

                5.  而且因?yàn)閟essionID本身有有效期,即使丟了,也可能很快失效,造成的損失可能沒那么大,而用戶名跟密碼丟了,那就大了

                6.  所以總結(jié)就是:

  •  然后,使用sessionID有哪些好處

                1.  方便直接根據(jù)ID查詢用戶對應(yīng)的session

                2.  加密的時(shí)候計(jì)算量小

                3.  安全性不會降低,甚至還更高一些

OK,通過獨(dú)立地解決純http機(jī)制會產(chǎn)生的問題,我們探討了cookie和session機(jī)制的本質(zhì)。而且想到:【使用http協(xié)議,服務(wù)器中不會保存客戶端的狀態(tài)】所產(chǎn)生的問題通過增加cookie和session機(jī)制解決了,是不是就意味著這個(gè)【狀態(tài)】跟cookie和session的關(guān)系非常緊密?

所以這個(gè)無狀態(tài)指的是【沒有對 本次會話 設(shè)置一個(gè)緩存區(qū),記錄這次會話的狀態(tài),緩存區(qū)包括服務(wù)器端和用戶端】但好像還是沒有點(diǎn)破關(guān)鍵(主要是覺得跟前面那些官方對狀態(tài)的說法不太吻合,甚至沒有對應(yīng)關(guān)系)

搜索Java知音公眾號,回復(fù)“后端面試”,送你一份Java面試題寶典

忽然我想到一個(gè)問題:一個(gè)有狀態(tài)的http是什么樣的?

1.很難直接想象有狀態(tài)的http是什么樣,因?yàn)閔ttp這種機(jī)制是天然無狀態(tài)的

2.那就類比一下吧,另一個(gè)天然有狀態(tài)的機(jī)制叫TCP

  •  如果有狀態(tài)的意思是它的每次請求是有聯(lián)系的,那么有狀態(tài)的TCP的樣子是:假如一份數(shù)據(jù)分了三份TCP包發(fā)送,那這個(gè)包上面會標(biāo)明這是第幾個(gè)包,會標(biāo)明這個(gè)包跟那幾個(gè)包是有聯(lián)系的,有什么聯(lián)系

3.但好像這個(gè)有狀態(tài)的TCP跟我們想要的有狀態(tài)的HTTP沒有關(guān)系,因?yàn)榧词姑看蝖ttp請求之間互相有聯(lián)系,它也不能解決上面提到的http無狀態(tài)的問題

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

4.1.假如每個(gè)http連接都有一個(gè)簽名,于是第一次登陸成功之后,服務(wù)器就知道了這個(gè)簽名是允許登陸的,于是之后所有同樣簽名的http連接都能登陸,這里利用了同一個(gè)用戶發(fā)出的http連接之間的同主人關(guān)系,這里解決了一個(gè)保持登錄狀態(tài)的問題

4.2.同樣,來嘗試?yán)眠@個(gè)【每次http請求之間互相有聯(lián)系】來解決上面碰到的那個(gè)問題【每一次操作都要與系統(tǒng)底層的數(shù)據(jù)庫進(jìn)行交互】,但想了半天確實(shí)無法進(jìn)行下去。往期:一百期面試題匯總

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

  1.  只有【每次http請求之間互相有聯(lián)系】這個(gè)條件,無法解決【每一次操作都要與系統(tǒng)底層的數(shù)據(jù)庫進(jìn)行交互】
  2.  因?yàn)楹苊黠@,要解決【每一次操作都要與系統(tǒng)底層的數(shù)據(jù)庫進(jìn)行交互】就必須在服務(wù)器端開辟一塊緩存區(qū)
  3.  不過如果你思考一下如何實(shí)現(xiàn)【每次http請求之間互相有聯(lián)系】,你就會發(fā)現(xiàn),它也需要在服務(wù)器端開辟一塊緩存區(qū)
  4.  所以【在服務(wù)器端開辟一塊緩存區(qū)】才是真正的條件,也就是說,它確實(shí)等價(jià)于【有狀態(tài)】
  5.  而且我也找到了這個(gè)【在服務(wù)器端開辟一塊緩存區(qū)】的條件跟前面那些官方對狀態(tài)的說法對應(yīng)的點(diǎn),那就是:
  •  通過在服務(wù)器端開辟一塊緩存區(qū),存儲、記憶、共享一些臨時(shí)數(shù)據(jù),你就可以:
  •  協(xié)議對于事務(wù)處理有記憶能力【事物處理】【記憶能力】
  •  對同一個(gè)url請求有上下文關(guān)系【上下文關(guān)系】
  •  每次的請求都是不獨(dú)立的,它的執(zhí)行情況和結(jié)果與前面的請求和之后的請求是直接關(guān)系的【不獨(dú)立】【直接關(guān)系】
  •  服務(wù)器中保存客戶端的狀態(tài)【狀態(tài)】

      6.  所以,這個(gè)狀態(tài),加上前面說的客戶端也有cookie,就是指,客戶端和服務(wù)器在臨時(shí)會話中產(chǎn)生的數(shù)據(jù)!而前面也說道了,使用緩存區(qū)保存臨時(shí)會話中的數(shù)據(jù)是多么重要

  •  所以狀態(tài)不僅包括不同URL訪問之間的關(guān)系,還有對其他URL訪問的數(shù)據(jù)記錄,還有一些其他的東西,所以更確切地說,狀態(tài)應(yīng)該是【實(shí)現(xiàn)了這些東西所憑借的后面的緩存空間】中的客戶的臨時(shí)數(shù)據(jù)
  •  cookie和session應(yīng)該是完全實(shí)現(xiàn)了有狀態(tài)這個(gè)功能

一種常見的對狀態(tài)的誤解:

  •  有人在解釋HTTP的無狀態(tài)時(shí),把它跟有連接對立,說是兩種方式,也就是如果想不無狀態(tài),就必須有連接,但其實(shí)不然
  •  有連接和無連接以及之后的Keep-Alive都是指TCP連接
  •  有狀態(tài)和無狀態(tài)可以指TCP也可以指HTTP
  •  TCP一直有狀態(tài),HTTP一直無狀態(tài),但是應(yīng)用為了有狀態(tài),就給HTTP加了cookie和session機(jī)制,讓使用http的應(yīng)用也能有狀態(tài),但http還是無狀態(tài)
  •  開始TCP是有連接,后來TCP無連接,再后來也就是現(xiàn)在TCP是Keep-Alive,有點(diǎn)像有連接 

 

責(zé)任編輯:龐桂玉 來源: Java知音
相關(guān)推薦

2020-06-30 08:41:38

HTTP無狀態(tài)協(xié)議

2015-03-25 11:47:57

HTTP協(xié)議SessionCookie

2024-04-30 11:14:19

KubernetesReplicaSet數(shù)量

2014-06-18 09:25:07

HTTP

2024-11-18 16:28:20

2013-12-09 09:56:30

NAT64IPv6stateful

2020-03-27 10:50:29

DSL 狀態(tài)機(jī)工具

2021-10-18 08:35:50

HTTPSHTTP協(xié)議

2024-05-30 11:53:51

2018-03-30 16:03:04

軟件無狀態(tài)”

2016-03-11 09:46:26

面向?qū)ο?/a>設(shè)計(jì)無狀態(tài)類

2022-06-01 12:00:54

HTTP狀態(tài)碼服務(wù)端

2023-05-26 16:38:38

2018-08-06 07:51:03

NFV網(wǎng)絡(luò)功能虛擬化

2024-12-19 15:41:17

2009-06-16 13:30:32

REST無狀態(tài)

2020-07-13 09:58:53

數(shù)字化轉(zhuǎn)型IT數(shù)據(jù)

2023-10-24 09:07:14

CookieSessionHTTP

2022-07-20 07:23:40

Kubernetes容器

2023-12-01 07:03:16

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號