正確的業(yè)務(wù)架構(gòu)遠(yuǎn)比正確的技術(shù)架構(gòu)重要
---- 斯沃.資基索德
經(jīng)驗(yàn)尚淺,不敢妄議大神寫的《大型網(wǎng)站技術(shù)架構(gòu)》,所以前面寫成學(xué)習(xí)筆記的形式,后面會(huì)聊些思考。希望能有所幫助。
作者在阿里當(dāng)過架構(gòu)師,現(xiàn)在就職英特爾。寫這本書的時(shí)候正值12306剛出來,頻頻奔潰。所以就寫了這本書,希望分享下相關(guān)經(jīng)驗(yàn)。前半部分細(xì)講了網(wǎng)站架構(gòu)的要素和解決方案,后半部分分析了淘寶維基百科等的具體案例,并且分享了如何做架構(gòu)師的一些經(jīng)驗(yàn)。對剛?cè)腴T后端開發(fā)或者想深入學(xué)習(xí)架構(gòu)設(shè)計(jì),進(jìn)行系統(tǒng)優(yōu)化的同學(xué)都是不錯(cuò)的學(xué)習(xí)書籍。
網(wǎng)站架構(gòu)的演化
1,原始時(shí)代,一臺(tái)服務(wù)器解決所有,經(jīng)典的LAMP,廉價(jià)服務(wù)器+開源軟件,網(wǎng)站就建起來了。
→ 等到訪問量越來越大,數(shù)據(jù)存儲(chǔ)空間吃緊了,所以。。。
2,使用三臺(tái)服務(wù)器,應(yīng)用,文件,數(shù)據(jù)庫分開。應(yīng)用服務(wù)器加CPU,文件服務(wù)器加大容量硬盤,數(shù)據(jù)庫服務(wù)器用更貴更快的硬盤。
→ 80%的訪問集中在20%的數(shù)據(jù)上,成為瓶頸
3,應(yīng)用服務(wù)器加本地緩存。
→ 本地緩存和應(yīng)用爭內(nèi)存
4,加遠(yuǎn)程獨(dú)立服務(wù)器放緩存,再不行上分布式緩存服務(wù)器,要多大有多大。
→單臺(tái)應(yīng)用服務(wù)器應(yīng)對請求數(shù)量有限,限制了并發(fā)能力
5,使用應(yīng)用服務(wù)器集群,可伸縮性大大增強(qiáng),再多用戶都不怕。
→用戶操作頻繁,高頻率的寫操作讓數(shù)據(jù)庫不堪重負(fù)
6,數(shù)據(jù)庫讀寫分離,配置主從數(shù)據(jù)庫,讀從從庫讀,寫就寫到主庫,利用主從復(fù)制讓數(shù)據(jù)一致
→網(wǎng)站內(nèi)容越來越豐富,響應(yīng)時(shí)間變長
7,上CDN服務(wù),靜態(tài)數(shù)據(jù)或者不頻繁更新的數(shù)據(jù)都到CDN。再利用反向代理,選擇距離用戶最近響應(yīng)最快的應(yīng)用服務(wù)器,大大加快響應(yīng)時(shí)間。
→寫數(shù)據(jù)操作量級上來了,數(shù)據(jù)服務(wù)器真的又撐不住了
8.1,我錢多,上分布式文件系統(tǒng)和分布式數(shù)據(jù)庫系統(tǒng),還慢就繼續(xù)加機(jī)器,總有快的時(shí)候。省心省力
8.2,沒錢,花點(diǎn)心思,根據(jù)業(yè)務(wù)對數(shù)據(jù)庫進(jìn)行拆分,將不同細(xì)分業(yè)務(wù)數(shù)據(jù)放到不同的數(shù)據(jù)服務(wù)器上,重點(diǎn)數(shù)據(jù)用更好的服務(wù)器。
→數(shù)據(jù)量大,檢索和生成報(bào)表巨慢
9,使用NoSQL放需要檢索的數(shù)據(jù),減輕原來數(shù)據(jù)庫服務(wù)器壓力
→業(yè)務(wù)復(fù)雜,技術(shù)開發(fā)難度提高
10,業(yè)務(wù)拆分,根據(jù)不同的產(chǎn)品線拆分技術(shù)開發(fā),看起來是一個(gè)網(wǎng)站,其實(shí)是不同的應(yīng)用來共同提供數(shù)據(jù)的
→業(yè)務(wù)拆分粒度越來越小,服務(wù)部署維護(hù)困難
11,分布式服務(wù),統(tǒng)一運(yùn)維
架構(gòu)模式
模式,描述了一個(gè)不斷重復(fù)發(fā)生的問題和該問題解決方案的核心。這樣,你就能一次次的使用該方案而不必做重復(fù)工作。
網(wǎng)站架構(gòu)要解決的問題,就這幾種:
- 高性能。就是要快!
- 高可用。7*24在線可用,掛了就不好了。
- 易伸縮。能隨訪問量,數(shù)據(jù)處理量的大小。進(jìn)行擴(kuò)容降容,不再門庭若市時(shí)候奔潰,不在人去樓空時(shí)浪費(fèi)錢。
- 可擴(kuò)展。師傅師傅大師兄又加需求了!好的架構(gòu),要隨業(yè)務(wù)的發(fā)展,無痛加功能加服務(wù)。
- 安全。不安全,以上都是白搭。
以上這些問題重復(fù)的出現(xiàn),也就形成了解決的模式。常見的模式:
- 分層。橫向切割。應(yīng)用層靠近用戶,負(fù)責(zé)具體業(yè)務(wù)和頁面展示,也就是常說的后臺(tái)和前端那部分,現(xiàn)在都是前后端分離了,也是分層的一種方法。服務(wù)器提供具體服務(wù)支持,比如訂單結(jié)算,購物車服務(wù)等,我現(xiàn)在工作大概就是在這一層,所以不要再問我后臺(tái)后端差別了啊啊啊。數(shù)據(jù)層,最后面,提供數(shù)據(jù)存儲(chǔ)的。
- 分割。縱向切割。將不同業(yè)務(wù)進(jìn)行分割,例如淘寶,購物車,搜索,廣告分割成不同的應(yīng)用,由獨(dú)立團(tuán)隊(duì)進(jìn)行負(fù)責(zé)。
- 分布式。不同應(yīng)用放不同物理機(jī)子,分布式部署可以對不同的應(yīng)用服務(wù)做到資源的有效分配。
- 集群。多臺(tái)服務(wù)器部署相同的應(yīng)用,通過負(fù)載均衡對外提供服務(wù),集群再提高更好的并發(fā)特性的同時(shí),也能提供系統(tǒng)的可用性,一臺(tái)掛了還有一臺(tái)嘛。
- 緩存。CDN,redis等等。緩存主要是兩個(gè)難點(diǎn),怎樣提供緩存命中率和設(shè)置過期時(shí)間避免臟讀。
- 異步。這一塊是重點(diǎn),異步架構(gòu)是典型的生產(chǎn)者消費(fèi)者模式,應(yīng)用使用隊(duì)列進(jìn)行消息傳遞而不直接互相調(diào)用。好處有二,可用性提高,如果后面的應(yīng)用掛了,前面的應(yīng)用還能繼續(xù)接收用戶請求,數(shù)據(jù)堆入隊(duì)列,等掛了的應(yīng)用重啟繼續(xù)消費(fèi)隊(duì)列就可以了。消除訪問波峰,突然的一波訪問,如果沒有異步處理,后端壓力會(huì)驟增,很可能就崩了,異步處理能將消息放進(jìn)消息隊(duì)列,后端依次處理,就不會(huì)有太大問題。
- 冗余。服務(wù)器隨時(shí)會(huì)掛,多備一臺(tái)服務(wù)器,數(shù)據(jù)多做一份備份,總是好事。雖然有點(diǎn)費(fèi)錢。
- 自動(dòng)化。發(fā)布過程自動(dòng)化,人為操作很容易出錯(cuò),當(dāng)然,需要自動(dòng)發(fā)布系統(tǒng)足夠好用。
- 安全。加密,驗(yàn)證碼,風(fēng)險(xiǎn)控制。
這本書主要就是圍繞以上內(nèi)容進(jìn)行講解,涉及的具體技術(shù)細(xì)節(jié)這里就不詳述了,技術(shù)棧一直在變,書里介紹的有些也有可能已經(jīng)過時(shí)了,但萬變不離其宗,應(yīng)當(dāng)朝著正確的方向,不斷學(xué)習(xí)。下面簡單聊一些個(gè)人書后的思考。
異步的問題
和人不同的是,網(wǎng)站系統(tǒng),任何可以晚點(diǎn)再做的事情都應(yīng)該晚點(diǎn)再做。
一般就是使用消息隊(duì)列將調(diào)用異步化,一個(gè)應(yīng)用接一個(gè)應(yīng)用的處理數(shù)據(jù),上游處理完了丟到下游,上游無需下游立即甚至壓根不用下游進(jìn)行反饋。
消息隊(duì)列的應(yīng)用,使系統(tǒng)的靈活性大大提高,起到很好的削峰作用。前面的應(yīng)用將短時(shí)間內(nèi)大量的請求存入消息隊(duì)列,推遲處理時(shí)間,使到后面吃大量內(nèi)存CPU的應(yīng)用不至于被壓垮。固定的消費(fèi)速率也使數(shù)據(jù)庫服務(wù)器的并發(fā)數(shù)得到控制。
但是,異步也會(huì)帶來很多麻煩的事情。
從前,有一個(gè)程序員,他有一個(gè)問題,他想用異步來解決,現(xiàn)在兩個(gè)他問題了有。
由于數(shù)據(jù)操作被異步化了,所以很難確定數(shù)據(jù)究竟處理完了沒有,也很難保障數(shù)據(jù)的一致性,前端應(yīng)用認(rèn)為處理完了,后端其實(shí)還沒好,就會(huì)出現(xiàn)很多問題,導(dǎo)致數(shù)據(jù)不一致,處理結(jié)果出現(xiàn)異常。這經(jīng)常需要額外的同步操作來進(jìn)行核實(shí)數(shù)據(jù),帶來額外的開銷。
另一個(gè)問題是,異步會(huì)導(dǎo)致數(shù)據(jù)的更新不及時(shí),當(dāng)然,這是異步的目的,同樣也是缺點(diǎn),看不同的場合。比如每日賣家報(bào)表,推遲個(gè)幾分鐘再統(tǒng)計(jì)出來沒有任何問題,但是像秒殺系統(tǒng),推廣限額系統(tǒng),就不能容忍數(shù)據(jù)統(tǒng)計(jì)延遲。在應(yīng)用了異步處理的架構(gòu)里,這些需求也就都需要額外處理,提供系統(tǒng)的復(fù)雜性。
所以,不要迷信技術(shù),不是任何網(wǎng)站都需要異步化的,也不是異步架構(gòu)里每個(gè)環(huán)節(jié)都需要異步化的。技術(shù)用到正確的地方才是好的技術(shù)。
應(yīng)用服務(wù)無狀態(tài)化的價(jià)值
墨菲定律,如果一個(gè)服務(wù)有幾率會(huì)掛,那它終有一天一定會(huì)掛給你看。
無狀態(tài)應(yīng)用服務(wù),就是此應(yīng)用不保存業(yè)務(wù)的上下文信息,而僅根據(jù)每次請求提交的數(shù)據(jù)進(jìn)行相應(yīng)的業(yè)務(wù)邏輯處理。部署兩臺(tái)服務(wù)器,請求無論被哪臺(tái)處理了,結(jié)果都是一樣的。這里可以聯(lián)想對比下函數(shù)式編程,道理有點(diǎn)類似。
無狀態(tài)的應(yīng)用,對整體的架構(gòu)設(shè)計(jì)有非常大的幫助。不用考慮宕機(jī)時(shí)會(huì)影響到業(yè)務(wù)數(shù)據(jù)處理和業(yè)務(wù)數(shù)據(jù)丟失。掛了,排查問題后重啟直接繼續(xù)干活,不用做任何額外的數(shù)據(jù)糾正,這讓和它配合的應(yīng)用都省心很多。
微服務(wù)做到無狀態(tài),需要編程經(jīng)驗(yàn),和對業(yè)務(wù)流程有清晰的認(rèn)識,這些還要繼續(xù)研究。
不要企圖用技術(shù)解決所有問題
網(wǎng)站的價(jià)值,在于能為用戶做什么,而不在于它是怎么做的。業(yè)務(wù)成就技術(shù),而不是相反,一個(gè)快速發(fā)展的網(wǎng)站,才能驅(qū)動(dòng)技術(shù)架構(gòu)不斷改進(jìn)。
正確的業(yè)務(wù)架構(gòu),遠(yuǎn)比正確的技術(shù)架構(gòu)重要。產(chǎn)品認(rèn)識到位,業(yè)務(wù)邏輯清楚,對技術(shù)的開發(fā)往往起到事半功倍的作用。
前面提到的分層分隔,怎樣分,和業(yè)務(wù)是密切相關(guān)的。都說程序員需要嚴(yán)密的邏輯思考能力,其實(shí),產(chǎn)品或者業(yè)務(wù)人員同樣需要嚴(yán)密的邏輯能力。將具體但繁雜的業(yè)務(wù)需求,發(fā)展方向,梳理清楚,1234拆分出層次分明,輕重緩急的細(xì)分業(yè)務(wù),組成清晰的業(yè)務(wù)架構(gòu)。
愿天下沒有難寫的代碼,只有賺錢的業(yè)務(wù),阿門。