在我的咨詢(xún)工作中,常常會(huì )碰到一些持如下觀(guān)點(diǎn)的人:“有些東西并不適合使用異步模式”——盡管他們自己也認可異步通訊 模式與生俱來(lái)的穩定性。一個(gè)常常被引用的例子就是用戶(hù)驗證——將用戶(hù)名和密碼對提交給后端系統驗證。為了討論方便,我假設后端系統使用了用戶(hù)數據庫。
問(wèn)題假設
為保證基本的安全性,我們假設密碼在被存儲前以某種散列算法編碼。同時(shí)假設網(wǎng)絡(luò )結構設計合理,Web服務(wù)器在 DMZ區域中得到隔離,它與應用服務(wù)器交互,應用服務(wù)器再與數據庫服務(wù)器通訊。當然,再在Web服務(wù)器 間(尤其是對用戶(hù)登錄等功能)應用輪循式(round- robin)負載均衡,也是一個(gè)很好的想法。
在深入討論這個(gè)問(wèn)題前,先來(lái)段開(kāi)場(chǎng)白。我發(fā)現人們不感冒異步模式,大多是因為沒(méi)有考慮應用的實(shí)際發(fā)布環(huán)境,或者解決方案不需要以多服務(wù)器、 Web Farm或多數據中心的分布式模式部署。
同步解決方案
在同步解決方案中,每個(gè)Web服務(wù)器對于每個(gè)用戶(hù)的登錄請求,都必須與應用服務(wù)器通訊。換句話(huà)說(shuō),應用服務(wù)器上的負載(數據庫服務(wù)器也是類(lèi)似的)將隨用戶(hù)登錄數正比上升。
我不想在這里對同步解決方案多加糾纏,因為以前已經(jīng)分析 得太多了。在這種系統中,數據庫最終都會(huì )成為瓶頸。為解決這個(gè)問(wèn)題,一般會(huì )采用數據庫分割方法 。很多大型站點(diǎn)配備有多個(gè)只讀數據庫——主數據庫負責數據更新,并將這些數據復制到只讀數據庫。如果在 LAMP架構下使用廉價(jià)的MySQL,這是一個(gè)很好 的解決方案;但如果運行Oracle或MS SQL Server,就不是那么回事了。
無(wú)論你在數據層動(dòng)什么手腳,都回避不了這個(gè)問(wèn)題。將數據訪(fǎng)問(wèn)操作限制在Web服務(wù)器內部不是很好嗎?即便使用廉價(jià)的 Apache,系統也會(huì )運行得更為流暢。異步解決方案的本質(zhì),就是以較小的內存代價(jià),換取對其他資源很大的節省。
異步解決方案
在異步 方案中,我們可將用戶(hù)名/散列密碼對緩存在Web服務(wù)器的內存中,并用緩存中的數據實(shí)現對用戶(hù)的驗證。首先,我們分析一下這種方法對內存的消耗量。
用戶(hù)名 一般不超過(guò)12個(gè)字符,我們在這里大方些,假設平均為32個(gè)字符。使用 Unicode編碼后,每用戶(hù)名占用64字節。散列加密的密碼因算法而異,會(huì )占用 256到512位,即最長(cháng)64字節。因此總的是 128字節。也就是說(shuō),使用Web服務(wù)器上1GB內存, 我們可以安全緩存8百萬(wàn)用戶(hù)名/密碼對。如果你有1百萬(wàn)用戶(hù) (也不錯了,行啊你),則只需要消耗128MB內存——這對于不需要花多少錢(qián)就可以配備2GB內存的服務(wù)器來(lái)說(shuō),小意思了。
新用戶(hù)注冊時(shí),我們可以在Web服務(wù)器緩存中檢查是否存在該用戶(hù)名。當然,若考慮到并發(fā)問(wèn)題,還需要通過(guò)數據庫再次檢查,但毫無(wú)疑問(wèn),數據庫的負載已經(jīng)大大降低。另外值得一提的是,在這種方案中,已經(jīng)不存在只讀數據 庫副本和數據復制操作。換個(gè)角度看,其實(shí)是我們的Web服務(wù)器充當了“數據庫副本”。
聯(lián)系客服