架构概述之架构演化、模式与核心要素
如何打造一個高可用、高性能、易擴展、可伸縮且安全的應用系統?相信這是困擾著無數開發者的難題,在這里我們以一個網站為例,來討論一下如何做好大型應用系統的架構設計。
架構演化發展歷程
大型網站的技術挑戰主要來自于龐大的用戶,高并發的訪問和海量的數據。
1
? ?
初始階段
大型網站都是從小型網站發展而來,小型網站最開始時沒有太多人訪問,只需要一臺服務器就綽綽有余,這時的網站架構如圖所示。
2
? ?
應用和數據分離
隨著業務的發展,一臺服務器逐漸不能滿足需求:越來越多的用戶訪問導致性能越來越差,越來越多的數據導致存儲空間不足。這時就需要將應用和數據分離。
應用和數據分離后整個網站使用三臺服務器:應用服務器、文件服務器和數據庫服務器,如圖所示。
這三臺服務器對硬件資源的要求各不相同,應用服務器需要處理大量的業務邏輯,因此需要更快更強大的 CPU;數據庫服務器需要快速磁盤檢索和數據緩存,因此需要更快的硬盤和更大的內存;文件服務器需要存儲大量用戶上傳的文件,因此需要更大的硬盤。
3
? ?
使用緩存
隨著用戶逐漸增多,網站又一次面臨挑戰:數據庫壓力太大導致訪問延遲,進而影響整個網站的性能,用戶體驗受到影響。網站訪問遵循二八定律:80%的業務訪問集中在 20%的數據上。既然大部分的業務訪問集中在一小部分數據上,那么如果把這一小部分數據緩存在內存中,是不是就可以減少數據庫的訪問壓力,提高整個網站的數據訪問速度,改善數據庫的寫入性能了呢?
網站使用的緩存可以分為兩種:緩存在應用服務器上的本地緩存和緩存在專門的分布式緩存服務器上的遠程緩存。本地緩存的訪問速度更快一些,但是受應用服務器內存限制,其緩存數據量有限,而且會出現和應用程序爭用內存的情況。遠程分布式緩存可以使用集群的方式,部署大內存的服務器作為專門的緩存服務器,可以在理論上做到不受內存容量限制的緩存服務,如圖所示。
4
? ?
使用應用服務器集群
使用緩存后,數據訪問壓力得到有效緩解,但是單一應用服務器能夠處理的請求連接有限,在網站訪問高峰期,應用服務器成為整個網站的瓶頸。
使用集群是解決高并發、海量數據問題的常用手段。當一臺服務器的處理能力、存儲空間不足時,不要企圖去換更強大的服務器,對大型網站而言,不管多么強大的服務器,都滿足不了網站持續增長的業務需求。這種情況下,更恰當的做法是增加一臺服務器分擔原有服務器的訪問及存儲壓力。
只要能通過增加一臺服務器的方式改善負載壓力,就可以以同樣的方式持續增加服務器不斷改善系統性能,從而實現系統的可伸縮性。應用服務器集群是可伸縮集群架構設計中較為簡單成熟的一種,如圖所示。
通過負載均衡調度服務器,可將來自用戶瀏覽器的訪問請求分發到應用服務器集群中的任何一臺服務器上,如果有更多的用戶,就在集群中加入更多的應用服務器,使應用服務器的負載壓力不再成為整個網站的瓶頸。
5
? ?
讀寫分離
網站在使用緩存后,使絕大部分數據讀操作訪問都可以不通過數據庫就能完成,但是仍有一部分讀操作和全部的寫操作需要訪問數據庫,在網站的用戶達到一定規模后,數據庫因為負載壓力過高而成為網站的瓶頸。
目前大部分的主流數據庫都提供主從熱備功能,通過配置兩臺數據庫主從關系,可以將一臺數據庫服務器的數據更新同步到另一臺服務器上。網站利用數據庫的這一功能,實現數據庫讀寫分離,從而改善數據庫負載壓力,如圖所示。
應用服務器在寫數據的時候,訪問主數據庫,主數據庫通過主從復制機制將數據更新同步到從數據庫,這樣當應用服務器讀數據的時候,就可以通過從數據庫獲得數據。為了便于應用程序訪問讀寫分離后的數據庫,通常在應用服務器端使用專門的數據訪問模塊,使數據庫讀寫分離對應用透明。
6
? ?
反向代理和 CDN
隨著業務不斷發展,用戶規模越來越大,不同地區的用戶訪問網站時,速度差別也極大。為了提供更好的用戶體驗,網站需要加速網站訪問速度。主要手段有使用 CDN 和反向代理,如圖所示。
CDN 和反向代理的基本原理都是緩存,區別在于 CDN 部署在網絡提供商的機房,使用戶在請求網站服務時,可以從距離自己最近的網絡提供商機房獲取數據;而反向代理則部署在網站的中心機房,當用戶請求到達中心機房后,首先訪問的服務器是反向代理服務器,如果反向代理服務器中緩存著用戶請求的資源,就將其直接返回給用戶。
7
? ?
使用分布式文件系統和分布式數據庫系統
數據庫經過讀寫分離后,從一臺服務器拆分成兩臺服務器,但是隨著網站業務的發展依然不能滿足需求,這時需要使用分布式數據庫。文件系統也是一樣,需要使用分布式文件系統,如圖所示。
分布式數據庫是網站數據庫拆分的最后手段,只有在單表數據規模非常龐大的時候才使用。不到不得已時,網站更常用的數據庫拆分手段是業務分庫,將不同業務的數據庫部署在不同的物理服務器上。
8
? ?
使用 NoSQL 和搜索引擎
隨著網站業務越來越復雜,對數據存儲和檢索的需求也越來越復雜,網站需要采用一些非關系數據庫技術如 NoSQL 和非數據庫查詢技術如搜索引擎,如圖所示。
9
? ?
業務拆分
大型網站為了應對日益復雜的業務場景,通過使用分而治之的手段將整個網站業務分成不同的產品線。具體到技術上,**將一個網站拆分成許多不同的應用,每個應用獨立部署維護。應用之間可以通過一個超鏈接建立關系(在首頁上的導航鏈接每個都指向不同的應用地址),也可以通過消息隊列進行數據分發,當然最多的還是通過訪問同一個數據存儲系統來構成一個關聯的完整系統。
10
? ?
分布式服務
隨著業務拆分越來越小,存儲系統越來越龐大,應用系統的整體復雜度呈指數級增加,部署維護越來越困難。
既然每一個應用系統都需要執行許多相同的業務操作,比如用戶管理、商品管理等,那么可以將這些共用的業務提取出來,獨立部署。由這些可復用的業務連接數據庫,提供共用業務服務,而應用系統只需要管理用戶界面,通過分布式服務調用共用業務服務完成具體業務操作,如圖所示。
大型網站的架構演化到這里,基本上大多數的技術問題都得以解決。
11
? ?
架構模式
為了解決應用系統面臨的高并發訪問、海量數據處理、高可靠運行等一系列問題與挑戰,大型互聯網公司在實踐中提出了許多解決方案,以實現高性能、高可用、易伸縮、可擴展、安全等各種技術架構目標。這些解決方案又被更多公司重復使用,從而逐漸形成架構模式。
12
? ?
分層
分層是企業應用系統中最常見的一種架構模式,將系統在橫向維度上切分成幾個部分,每個部分負責一部分相對比較單一的職責,然后通過上層對下層的依賴和調用組成一個完整的系統。
通過分層,可以更好地將一個龐大的軟件系統切分成不同的部分,便于分工合作開發和維護。各層之間具有一定的獨立性,只要維持調用接口不變,各層可以根據具體問題獨立演化發展而不需要其他層必須做出相應調整。但是分層架構也有一些挑戰,就是必須合理規劃層次邊界和接口,在開發過程中,嚴格遵循分層架構的約束,禁止跨層調用及逆向調用。在實踐中,大的分層結構內部還可以繼續分層。分層架構是邏輯上的,三層結構可以部署在同一個物理機器上。但是隨著網站業務的發展,必然需要對已經分層的模塊分離部署,使網站擁有更多的計算資源以應對越來越多的用戶訪問。在網站架構中,通常將應用系統分為應用層、服務層、數據層,如下圖所示。
13
? ?
分割
分層是將軟件在橫向方面進行切分,分割則是在縱向方面對軟件進行切分。網站越大,功能越復雜,服務和數據處理的種類也越多。將這些不同的功能和服務分割開來,包裝成高內聚低耦合的模塊單元,一方面有助于軟件的開發和維護;另一方面,便于不同模塊的分布式部署,提高網站的并發處理能力和功能擴展能力。大型網站分割的粒度可能會很小。比如在應用層,將不同業務進行分割,例如將購物、論壇、搜索、廣告分割成不同的應用,由獨立的團隊負責,部署在不同的服務器上。
14
? ?
分布式
對于大型網站,分層和分割的一個主要目的是為了切分后的模塊便于分布式部署,即將不同模塊部署在不同的服務器上,通過遠程調用協同工作。分布式意味著可以使用更多的資源完成同樣的功能,能夠處理的并發訪問和數據量也更大。但分布式在解決網站高并發問題的同時也帶來了其他問題。典型的有下面幾點:
意味著服務調用必須通過網絡,這可能會對性能造成比較嚴重的影響。
服務器越多,宕機的概率也就越大,造成的服務不可用可能會導致很多應用不可訪問,使網站可用性降低。
數據在分布式的環境中保持數據一致性非常困難,分布式事務也難以保證。
系統依賴錯綜復雜,開發管理維護困難。
因此分布式設計要根據具體情況量力而行。常用的分布式方案有:分布式服務、分布式數據庫、分布式計算、分布式配置、分布式鎖和分布式文件系統等。
15
? ?
集群
使用分布式雖然已經將分層和分割后的模塊獨立部署,但是對于用戶訪問集中的模塊,還需要將獨立部署的服務器集群化,即多臺服務器部署相同應用構成一個集群,通過負載均衡設備共同對外提供服務。
因為服務器集群有更多服務器提供相同服務,因此可以提供更好的并發性,當有更多用戶訪問的時候,只需要向集群中加入新的機器即可。同時當某臺服務器發生故障時,負載均衡設備或者系統的失效轉移機制會將請求轉發到集群中其他服務器上,提高系統的可用性。
16
? ?
緩存
緩存就是將數據存放在距離計算最近的位置以加快處理速度。緩存是改善軟件性能的第一手段,在復雜的軟件設計中,緩存幾乎無處不在。比如常見的反向代理、Redis(未開啟持久化)、CDN 等。
使用緩存有兩個前提條件,一是數據訪問熱點不均衡,某些數據會被更頻繁的訪問,這些數據應該放在緩存中;二是數據在某個時間段內有效,不會很快過期,否則緩存的數據就會因已經失效而產生臟讀,影響結果的正確性。
緩存除了可以加快數據訪問速度,還可以減輕后端應用和數據存儲的負載壓力,網站數據庫幾乎都是按照有緩存的前提進行負載能力設計的。
17
? ?
異步
應用系統的一個重要目標是降低耦合性。系統解耦的手段除了前面提到的分層、分割、分布式等,還有一個重要手段是異步,業務之間的消息傳遞不是同步調用,而是將一個業務操作分成多個階段,每個階段之間通過共享數據的方式異步執行進行協作。
異步架構是典型的生產者消費者模式,兩者不存在直接調用,只要保持數據結構不變,彼此功能實現可以隨意變化而不互相影響,這對網站擴展新功能非常便利。除此之外,使用異步消息隊列還有如下優點:
提高系統可用性。消費者服務器發生故障,數據會在消息隊列服務器中存儲堆積,生產者服務器可以繼續處理業務請求,系統整體表現無故障。
消費者服務器恢復正常后,繼續處理消息隊列中的數據。
加快網站響應速度。處在業務處理前端的生產者服務器在處理完業務請求后,將數據寫入消息隊列,不需要等待消費者服務器處理就可以返回,響應延遲減少。
消除并發訪問高峰。用戶訪問網站是隨機的,存在訪問高峰和低谷。
使用消息隊列將突然增加的訪問請求數據放入消息隊列中,等待消費者服務器依次處理,就不會對整個網站負載造成太大壓力。
但需要注意的是,使用異步方式處理業務可能會對用戶體驗、業務流程造成影響,需要網站產品設計方面的支持。
18
? ?
冗余
網站需要 7×24 小時連續運行,但是服務器隨時可能出現故障,特別是服務器規模比較大時,出現某臺服務器宕機是必然事件。要想保證在服務器宕機的情況下網站依然可以繼續服務,不丟失數據,就需要一定程度的服務器冗余運行,數據冗余備份,這樣當某臺服務器宕機時,可以將其上的服務和數據訪問轉移到其他機器上。
訪問和負載很小的服務也必須部署至少兩臺服務器構成一個集群,其目的就是通過冗余實現服務高可用。數據庫除了定期存檔進行冷備份外,還需要對數據庫進行主從分離,實時同步實現熱備份。
19
? ?
自動化與安全
目前應用系統的自動化架構設計主要集中在發布運維方面。包括自動化發布、自動化代碼管理、自動化測試、自動化安全監測、自動化部署、自動化監控、自動化告警、自動化失效轉移與恢復、自動化降級和自動化分配資源等。
系統在安全架構方面也積累了許多模式:通過密碼和手機校驗碼進行身份認證;登錄、交易等操作需要對網絡通信進行加密,網站服務器上存儲的敏感數據如用戶信息等也進行加密處理;為了防止機器人程序濫用網絡資源攻擊網站,網站使用驗證碼進行識別;對于常見的用于攻擊網站的 XSS 攻擊、SQL 注入、進行編碼轉換等相應處理;對于垃圾信息、敏感信息進行過濾;對交易轉賬等重要操作根據交易模式和交易信息進行風險控制。
20
? ?
架構核心要素
關于什么是架構,維基百科是這樣定義的:“有關軟件整體結構與組件的抽象描述,用于指導大型軟件系統各個方面的設計”。
一般說來,除了功能需求外,軟件架構還需要關注性能、可用性、伸縮性、擴展性和安全性這 5 個要素。
21
? ?
性能
性能是網站的一個重要指標,任何軟件架構設計方案都必須考慮可能會帶來的性能問題。也正是因為性能問題幾乎無處不在,所以優化網站性能的手段也非常多,主要的方式可以總結如下:
瀏覽器:瀏覽器緩存、使用頁面壓縮、合理布局頁面、減少 Cookie 傳輸等
CDN 和反向代理
本地緩存和分布式緩存
異步消息隊列
應用層:服務器集群
代碼層:多線程、改善內存管理等
數據層:索引、緩存、SQL 優化等,以及合理使用 NoSQL 數據庫
22
? ?
可用性
網站高可用的主要手段是冗余,應用部署在多臺服務器上同時提供訪問,數據存儲在多臺服務器上互相備份,任何一臺服務器宕機都不會影響應用的整體可用,也不會導致數據丟失。
對于應用服務器而言,多臺應用服務器通過負載均衡設備組成一個集群共同對外提供服務,任何一臺服務器宕機,只需把請求切換到其他服務器即可,但是一個前提條件是應用服務器上不能保存請求的會話信息。
對于存儲服務器,需要對數據進行實時備份,當服務器宕機時需要將數據訪問轉移到可用的服務器上,并進行數據恢復以保證繼續有服務器宕機的時候數據依然可用。
除了運行環境,網站的高可用還需要軟件開發過程的質量保證。通過預發布驗證、自動化測試、自動化發布、灰度發布等手段,減少將故障引入線上環境的可能。
23
? ?
伸縮性
衡量架構伸縮性的主要標準有:是否可以用多臺服務器構建集群,是否容易向集群中添加新的服務器,加入新的服務器后是否可以提供和原來的服務器無差別的服務,集群中可容納的總的服務器數量是否有限制。對于應用服務器集群,通過使用合適的負載均衡設備就可以向集群中不斷加入服務器。對于緩存服務器集群,需要使用高效的緩存路由算法,避免加入新服務器導致路由大面積失效。
關系數據庫很難做到大規模集群的可伸縮性,因此關系數據庫的集群伸縮性方案必須在數據庫之外實現,通過路由分區等手段將部署有多個數據庫的服務器組成一個集群。至于大部分 NoSQL 數據庫產品,由于其先天就是為海量數據而生,因此其對伸縮性的支持通常都非常好。
24
? ?
擴展性
衡量架構擴展性的主要標準就是不同產品之間是否很少耦合。在網站增加新的業務產品時,是否可以實現對現有產品透明無影響,不需要任何改動或者很少改動既有業務功能就可以上線新產品。
網站可伸縮架構的主要手段是事件驅動架構和分布式服務。
事件驅動架構在網站通常利用消息隊列實現,將用戶請求和其他業務事件構造成消息發布到消息隊列,消息的處理者作為消費者從消息隊列中獲取消息進行處理。通過這種方式將消息產生和消息處理分離開來,可以透明地增加新的消息生產者任務或者新的消息消費者任務。
分布式服務則是將業務和可復用服務分離開來,通過分布式服務框架調用。新增產品可以通過調用可復用的服務實現自身的業務邏輯,而對現有產品沒有任何影響。可復用服務升級變更的時候,也可以通過提供多版本服務對應用實現透明升級,不需要強制應用同步變更。
25
? ?
安全性
網站的安全架構就是保護網站不受惡意訪問和攻擊,保護網站的重要數據不被竊取。衡量網站安全架構的標準就是針對現存和潛在的各種攻擊與竊密手段,是否有可靠的應對策略。
總結
以上是生活随笔為你收集整理的架构概述之架构演化、模式与核心要素的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 536 开心的mdd
- 下一篇: 前端Chrome调试技巧汇总