《大型网站技术架构》读书笔记之七:随需应变之网站的可扩展架构
來源:http://www.cnblogs.com/edisonchou/p/3862389.html
此篇已收錄至《大型網站技術架構》讀書筆記系列目錄貼,點擊訪問該目錄可獲取更多內容。
一、可伸縮與可擴展—傻傻分不清楚
上篇筆記我們學習了可伸縮架構,但在實際場合中,包括許多架構師也常常混淆可伸縮和可擴展,用可擴展表示伸縮性。那么在此,跟隨作者我們來理清這兩個概念,避免我們以后對其傻傻分不清楚。
(1)擴展性(Extensibiltiy)
指對現有系統影響最小的情況下,系統功能可持續擴展或提升的能力。我們不禁想到了面向對象中一大原則:開閉原則,對擴展開放,對修改封閉。也就說,當系統新增一個功能時,不需要對現有系統的結構和代碼進行修改。
(2)伸縮性(Scalability)
指系統能夠通過增加(或減少)自身資源規模的方式增強(或減少)自己計算事務的能力。在網站架構中,通常是指利用集群的方式增加服務器數量,從而提高系統的整體事務吞吐能力。
設計網站可擴展架構的核心思想是:模塊化,并在此基礎之上降低模塊間的耦合,提高模塊的復用性。在大型網站中,這些模塊通過分布式部署的方式,獨立的模塊部署在獨立的服務器(集群)上,從物理上分離模塊之間的耦合關系,進一步降低耦合性從而提高復用性。
二、利用分布式消息隊列降低系統耦合性
上面我們提到說要分離模塊之間的耦合,如果模塊之間不存在直接調用,那么新增模塊或者修改模塊就對其他模塊的影響最小,這樣系統的可擴展性無疑會更好一些。那么,有沒有一種架構是基于如此考慮而設計的呢?于是,我們將眼光轉向一個名叫“事件驅動”的架構。
2.1 事件驅動架構
根據事件驅動架構(Event Driven Architecture)的定義:通過在低耦合的模塊之間傳輸消息,以保持模塊的松散耦合,并借助事件消息的通信完成模塊間合作。典型的EDA架構就是操作系統中常見的生產者消費者模式。在大型網站架構中,具體實現手段有很多,但是最常見的是分布式消息隊列。
如上圖所示,消息隊列利用發布—訂閱模式工作,消息發送者發布消息,一個或多個消息接受者訂閱消息。消息發送者是消息源,在對消息進行處理后發送至分布式消息隊列,消息接收者從分布式消息隊列獲取該消息后繼續進行處理。可以明顯看出,發送者與接受者之間沒有直接耦合,消息發送者只需將消息發送給分布式消息隊列即操作結束,而消息接受者也只需要從分布式消息隊列獲取消息后進行處理,不需要知道該消息從何而來。因此,對于新增業務,只要對該類消息感興趣,即可訂閱該消息,對原有系統和業務沒有任何影響,從而實現網站業務的可擴展設計。
2.2 分布式消息隊列
隊列是一種先進先出的數據結構,分布式消息隊列則看以看作是將這種數據結構部署到獨立服務器上,應用程序看以通過遠程訪問接口使用分布式消息隊列,進行消息存取操作,進而實現分布式的異步調用。
如上圖所示,我們可以明確三個步湊:
①消息生產者應用程序通過遠程訪問接口將消息推送給消息隊列服務器,消息隊列服務器將消息寫入本地內存隊列后馬上返回成功響應給消息生產者。
②消息隊列服務器根據消息訂閱列表查找訂閱該消息的消費者應用程序,將消息隊列中的消息按照先進先出的原則將消息通過遠程通信接口發送給消費者應用程序;
③消費者應用程序接收到推送過來的消息之后進行相關的一系列處理,過程終止;
PS:那么,有沒有這樣一種情況:消息隊列服務器宕機后導致消息丟失。事實上,這種情況的確存在于實際的運維過程中。那么,我們如何來避免呢?這時,作者給出了一個方案:如果消息隊列服務器宕機造成消息丟失,會將消息成功發送到消息隊列的消息存儲在消息生產者服務器,等消息真正被消息消費者服務器處理后才刪除消息。在消息隊列服務器宕機后,生產者服務器會選擇分布式消息隊列服務器集群中其他的服務器發布消息。
另外,有關于分布式消息隊列的實踐可以采用NoSQL產品來構建,例如Redis就提供了隊列數據類型,可以方便地構建分布式消息隊列,如果你有興趣,也可以參閱我的另一篇博文:《使用Redis作為消息隊列服務應用場景案例》
三、利用分布式服務打造可復用的業務平臺
如果說分布式消息隊列通過消息對象分解系統耦合性,不同子系統處理同一個消息;那么分布式服務則通過接口分解系統耦合性,不同子系統通過相同的接口描述進行服務調用。
3.1 巨無霸的應用系統帶來的問題
網站由小到大的演化過程中,表現為整個網站是由單一系統逐步膨脹發展變化而來的,隨著網站功能的日益復雜,網站應用系統會逐漸成為一個巨無霸,如下圖所示。可以看出,一個應用中聚合了大量的應用和服務組件,這個巨無霸給整個網站的開發(編譯麻煩、代碼分支管理困難)、維護(新增業務困難)和部署(部署困難)都帶來了巨大的麻煩。
3.2 拆分,拆分還是拆分
解決方案還是我們多次提到的拆分,將模塊獨立部署,降低系統耦合性。拆分又分為:橫向拆分和縱向拆分。這里我們再次回顧一下這兩種方式:
(1)縱向拆分:將一個大應用拆分為多個小應用,如果新增的業務較為獨立,那么就直接將其設計部署為一個獨立的Web應用系統;
(2)橫向拆分:將可以復用的業務拆分出來,獨立部署為分布式服務,新增業務只需要調用這些分布式服務即可,不需要依賴于具體的模塊代碼。如果模塊內業務邏輯發生變化時,只要接口保持一致就不會影響業務程序和其他模塊。
四、可擴展的數據結構
傳統的關系數據庫為了保證關系運算(通過SQL語句)的正確性,在設計表結構的時候就需要制定表的Schema—字段名稱、數據類型等,還要遵循制定的設計范式(例如:1NF、2NF、3NF等等)。這些規范帶來的一個問題就是僵硬的數據結構難以面對需求變更帶來的挑戰,有些系統設計者通過預先設計一些冗余字段來應付(在我所實習的一年里,我見過很多次這種設計,雖然可以解決問題,但從設計學來說,真的好Shit),但這顯然是一種糟糕的數據庫設計。
那么,有木有辦法能夠做到可擴展的數據結構設計呢?是否可以不需要修改表結構就可以新增字段呢?答案是肯定的,目前許多NoSQL數據庫使用的ColumnFamily(列族)設計就是一個解決方案。ColumnFamily最早在Google的BigTable中使用,這是一種面向列族的稀疏矩陣存儲格式。或許這么說大家還是不明白,但可以通過下圖來理解:
這是一個學生基本信息表,不同學生的聯系方式不同,選修的課程也不同,而且在將來會有更多的聯系方式和課程加入這張表,如果按照傳統的數據庫設計,無論提前預設多少冗余字段都不夠用,捉襟見肘,疲于應付。而是用ColumnFamily結構的NoSQL數據庫,創建表的時候,只需要指定ColumnFamily的名字,無需指定字段(Column),可以在數據寫入時再指定,通過這種方式,數據表可以包含數百萬的字段,使應用程序的數據結構可以隨意擴展。
五、利用開放平臺建設網站生態圈
網站的價值在于為他的用戶創造價值,大型網站為了更好地服務自己的用戶,會開發更多的增值服務,會把網站內部的服務封裝一些調用接口開放出去,供外部的第三方開發者使用,這個提供開放接口的平臺被稱作開放平臺。第三方開發者利用這些開放的接口開發應用程序(APP)或者網站,為更多的用戶提供價值。這樣一來,網站、用戶、第三方開發者相互依賴,形成一個網站的生態圈,即為用戶提供更多的價值,也提高了網站和第三方開發者的競爭能力和盈利能力。
目前BAT等國內互聯網巨頭都建設有自己的開放平臺,力圖利用自己龐大的用戶群吸引第三方開發者,打造一個更加龐大的航母戰斗群,在市場競爭中呼風喚雨,立于不敗之地。
六、學習小結
網站不停上新產品是其生存的本能,誰能更快更好地退出更多的新產品,誰就活得更滋潤。馬克思的勞動價值理論在IT業得到了印證:產品的內在價值在于勞動的時間,而勞動的時間不在于個體付出的勞動時間,而在于行業一般勞動時間,資本家只會為行業一般勞動時間買單,如果你的效率低于行業一般時間,對不起,請你資源加班。
我又想起我在CDEIC實習的這一年里,加了好多個班,現在看來,如果我們當時的系統有一個更具擴展性的系統架構,可以更快速地快發新產品,也許我們就就能夠按時下班,有女朋友的多陪陪女朋友吃飯看電影之類的,沒女朋友的就去發展發展女朋友之類的(貌似我還單身就是加班加太多了,沒時間找女朋友?),或者讀讀書,聽聽歌,散散步,對月當歌,訴說人生幾何了。
本章思維導圖
?
作者:周旭龍
出處:http://www.cnblogs.com/edisonchou/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
總結
以上是生活随笔為你收集整理的《大型网站技术架构》读书笔记之七:随需应变之网站的可扩展架构的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 《程序员》2月精彩内容:互联网应用架构面
- 下一篇: 应用文(说一说应用文的简介)
