問題說明
在昨天的總結(jié)中云稚,對(duì)于6月10日的Workshop進(jìn)行了一定程度的歸納和總結(jié)暇唾,在后續(xù)與老師的討論中,發(fā)現(xiàn)部分未接觸過的內(nèi)容只是理解了字面上的意思悦污,并未進(jìn)行深入的思考,先對(duì)其中部分問題的解答做記錄钉蒲,以備日后查閱切端。
一、 HTTP請(qǐng)求的狀態(tài)問題
原文如下:
互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議顷啼,是一個(gè)無狀態(tài)協(xié)議踏枣。這意味著,所有的狀態(tài)都保存在服務(wù)器端钙蒙。因此茵瀑,
如果客戶端想要操作服務(wù)器,必須通過某種手段躬厌,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)除师。
而這種轉(zhuǎn)化是建立在表現(xiàn)層之上的犁跪,所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"炫加。
(引用自:阮一峰博客“理解restful構(gòu)架”)
原文中提到,互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議屹篓,是一個(gè)無狀態(tài)的協(xié)議,在昨天的總結(jié)中匙奴,只是對(duì)這個(gè)概念做了單純的記憶堆巧,沒有去理解何為狀態(tài)。
協(xié)議的狀態(tài):
百度百科給出的解釋是:
協(xié)議的狀態(tài)是指下一次傳輸可以“記住”這次傳輸信息的能力.
——百度百科
無狀態(tài)協(xié)議:[ HTTP協(xié)議 ]:
前文中提到了饥脑,互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議恳邀,是一個(gè)無狀態(tài)的協(xié)議。說明了HTTP協(xié)議中灶轰,為了保證服務(wù)器的內(nèi)存谣沸,HTTP不會(huì)為了下次連接而維護(hù)這次連接所傳輸?shù)男畔ⅰ?/p>有狀態(tài)協(xié)議:[網(wǎng)絡(luò)游戲通信協(xié)議(這里我沒有查到具體使用的協(xié)議,后續(xù)了解到會(huì)補(bǔ)充進(jìn)來)]
眾所周知笋颤,網(wǎng)絡(luò)游戲在進(jìn)行過程中乳附,需要一次登錄,登錄過后服務(wù)器不會(huì)再去要求登錄才能訪問URI伴澄,這就說明了赋除,在用戶第一次登陸之后,用戶自身的請(qǐng)求會(huì)攜帶一個(gè)“已登陸”的狀態(tài)非凌。后續(xù)用戶跟服務(wù)器的交互過程中举农,服務(wù)器會(huì)自動(dòng)識(shí)別這個(gè)“已登錄”的狀態(tài),而不會(huì)再要求用戶去登陸才能訪問資源敞嗡。
無狀態(tài)協(xié)議在一些特定情況下的補(bǔ)充:
Q:已知HTTP協(xié)議是一個(gè)無狀態(tài)的協(xié)議颁糟,那用戶在訪問類似Baidu這樣的網(wǎng)站時(shí),已登錄的狀態(tài)該如何處理喉悴?
A:利用cookie棱貌。
1、當(dāng)你發(fā)送第一個(gè)請(qǐng)求的時(shí)候箕肃,服務(wù)器會(huì)生成一個(gè)隨機(jī)的字符串婚脱,然后在服務(wù)器空間內(nèi)分配一段內(nèi)存空間,這個(gè)內(nèi)存段的索引就是這個(gè)字符串(為方便敘述勺像,這個(gè)字符串暫定為123)障贸;
2、“123”會(huì)隨著HTTP的Response返回給瀏覽器吟宦,瀏覽器會(huì)將它存入Cookie中篮洁;
3、此時(shí)我們輸入用戶名和密碼督函,會(huì)像服務(wù)器發(fā)送登錄請(qǐng)求,request中會(huì)包含“123”;
4辰狡、服務(wù)器接受到請(qǐng)求后锋叨,驗(yàn)證用戶名密碼的正確性,驗(yàn)證后會(huì)根據(jù)索引“123”宛篇,找到之前分配的內(nèi)存空間(session)娃磺,在空間內(nèi)加入“已登陸”的標(biāo)志。
5叫倍、再次之后偷卧,我們的每個(gè)請(qǐng)求都會(huì)帶有“123”這個(gè)索引,服務(wù)器會(huì)根據(jù)這個(gè)索引找到內(nèi)存段吆倦,如果有“已登陸”的標(biāo)志听诸,有則正常訪問,無則跳轉(zhuǎn)登陸界面蚕泽。
二晌梨、RestAPI的架構(gòu)問題
根據(jù)上述,我們可以獲得一個(gè)信息须妻,在所有http都會(huì)帶有cookie的先決條件下仔蝌,任何http請(qǐng)求都會(huì)由request帶來狀態(tài),也就是說service理論是能夠知道請(qǐng)求的狀態(tài)的荒吏。
但根據(jù)前文講述敛惊,服務(wù)器不應(yīng)該知道請(qǐng)求的狀態(tài),否則會(huì)造成過度的負(fù)載绰更,有悖于我們之前講述的RestAPI的架構(gòu)瞧挤。所以在可用性上,RestAPI的架構(gòu)風(fēng)格做了兩個(gè)方面的約束:
- 狀態(tài)由客戶端提供动知;
- Service不保存狀態(tài)皿伺。
在這兩個(gè)方面的約束下,我們可以得知盒粮,狀態(tài)需要一個(gè)空間來存放鸵鸥,那么這時(shí)候有兩種選擇:
1、 存放在數(shù)據(jù)庫中
這種方法簡明有效丹皱,但同時(shí)也面臨一定的風(fēng)險(xiǎn)妒穴,數(shù)據(jù)庫本身的存儲(chǔ)就具有一定的風(fēng)險(xiǎn),所以這里我們不提倡
2摊崭、存放在類似redis集群式的內(nèi)存存儲(chǔ)里
這種方法具有速度快讼油、多個(gè)備份節(jié)點(diǎn)等優(yōu)點(diǎn)
綜上,現(xiàn)在的RestAPI構(gòu)架所提倡的組合:
客戶端——Service——State Storage ——數(shù)據(jù)庫呢簸。
ps:新名詞解釋:redis:
redis是一個(gè)key-value存儲(chǔ)系統(tǒng)矮台。和Memcached類似乏屯,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)瘦赫、list(鏈表)辰晕、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)确虱。這些數(shù)據(jù)類型都支持push/pop含友、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的校辩。在此基礎(chǔ)上窘问,redis支持各種不同方式的排序。與memcached一樣宜咒,為了保證效率惠赫,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件荧呐,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步汉形。
——來自百度百科
(于6月25日補(bǔ)充,未完待續(xù))