大型網站技術架構

第一篇:概述

傳統的企業應用系統主要面對的技術挑戰是處理複雜凌亂、千變萬化的所謂業務邏輯,而大型網站主要面對的技術挑戰是處理超大量的用戶訪問和海量的數據處理;前者的挑戰來自功能性需求,後者的挑戰來自非功能性需求;功能性需求也許還有“人月神話”聊以自慰,通過增加人手解決問題,而非功能需求大多是實實在在的技術難題,無論有多少工程師,做不到就是做不到。

“好的設計絕對不是模仿、不是生搬硬套某個模式,而是在對問題深刻理解之上的創造與創新,即使是‘微創新’,也是讓人耳目一新的似曾相識。

京東促銷不能購買的例子

能夠正常訪問購物車,卻不能成功購買,問題應該是出在訂單系統,B 2C網站生成一個訂單需要經歷扣減庫存、扣減促銷資源、更新用戶賬戶等一系列操作這些操作大多是數據庫事務操作,沒有辦法通過緩存等手段來減輕數據庫服務器負載壓力,如果事前沒有設計好數據庫伸縮性架構,那麼京東的技術團隊將遇到一個大麻煩

1.大型網站架構演化

如何打造一個高可用、高性能、易擴展、可伸縮且安全的網站?如何讓網站隨應用所需靈活變動,即使是山寨他人的產品,也可以山寨的更高、更快、更強,一年時間用戶數從零過億呢?

1.1大型網站軟件系統的特點

有以下特點:

1.高併發,大流量
2.高可用:系統24小時不間斷服務
3.海量數據
4.用戶分佈廣泛,網絡情況複雜
5.安全環境惡劣
6.需求快速變更,發佈頻繁
7.漸進式發展

1.2大型網站架構演化發展歷程

1.初始階段的網站架構

應用程序,數據庫,文件等所有的資源都在一臺服務器上。

2.應用服務和數據服務分離

應用和數據分離後整個網站使用三臺服務器:應用服務器,文件服務器和數據庫服務器。如下圖所示:

這三臺服務器對硬件資源的要求各不相同:

1.應用服務器需要處理大量的業務邏輯,因此需要更快更強大的CPU
2.數據庫服務器需要快速磁盤檢索和數據緩存,因此需要更快的硬盤和更大的內存
3.文件服務器需要存儲大量用戶上傳的文件,因此需要更大的磁盤

隨着用戶逐漸增多,網站又一次面臨挑戰:數據庫壓力太大導致訪問延遲,進而影響整個網站的性能,用戶體驗受到影響。

3.訪問緩存改善網站性能

網站訪問特點和現實世界的財富分配一樣遵循二八定律:80%的業務訪問集中在20%的數據上

網站使用的緩存可以分爲兩種:緩存在1.應用服務器上的本地緩存和緩存在專門的2.分佈式緩存服務器上的遠程緩存。本地緩存的訪問速度更快一些,但是受應用服務器內存限制,其緩存數據量有限,而且會出現和應用程序爭用內存的情況。遠程分佈式緩存可以使用集羣的方式,部署大內存的服務器作爲專門的緩存服務器,可以在理論上做到不受內存容量限制的緩存服務,如圖:

使用緩存後,數據訪問壓力得到有效緩解,但是單一應用服務器能夠處理的請求連接有限,在網站高峯期,應用服務器成爲整個網站的瓶頸

4.使用應用服務器集羣改善網站的併發處理能力

使用集羣是網站解決高併發、海量數據問題的常用手段。當一臺服務器的處理能力、存儲空間不足時,不要企圖去換更強大的服務器,對大型網站而言,不管多麼強大的服務器,都滿足不了網站持續增長的業務需求。這種情況下,更恰當的做法是增加一臺服務器分擔原有服務器的訪問及存儲壓力。架構如圖:

5.數據庫讀寫分離

目前大部分的主流數據庫都提供主從熱備功能,通過配置兩臺數據庫主從關係,可以將一臺數據庫服務器的數據更新同步到另一臺服務器上。網站利用數據庫的這一功能,實現數據庫讀寫分離,從而改善數據庫負載壓力。如圖:

6.使用反向代理和CDN加速網站響應

CDN和反向代理的基本原理都是緩存,區別在於CDN部署在網絡提供商的機房,使用戶在請求網站服務時,可以從距離自己最近的網絡提供商機房獲取數據;而反向代理則部署在網站的中心機房,當用戶請求到達中心機房後,首先訪問的服務器是反向代理服務器,如果反向代理服務器中緩存着用戶請求的資源,就將其直接返回給用戶。架構如圖:

使用CDN和反向代理的目的是儘早返回數據給用戶,一方面加快用戶訪問速度,另一方面也減輕了後端服務器的負載壓力。

7.使用分佈式文件系統和分佈式數據庫系統

分佈式數據庫是網站數據庫拆分的最後手段,只有在單表數據規模非常龐大的時候才使用。不到不得已時,網站更常用的數據庫拆分手段是業務分庫,將不同業務的數據庫部署在不同的物理服務器上

8.使用NoSQL和搜索引擎

9.業務拆分

10.分佈式服務

既然每一個應用系統都需要執行許多相同的業務操作,比如用戶管理、商品管理等,那麼可以將這些共用的業務提取出來,獨立部署。由這些可複用的業務連接數據庫,提供共用業務服務,而應用系統只需要管理用戶界面,通過分佈式服務調用共用業務服務完成具體業務操作,如圖:

1.4網站架構設計誤區

誤區:

1.一味追隨大公司的解決方案
2.爲了技術而技術
3.企圖用技術解決所有問題

比如說12306網站:

12306真正的問題其實不在於它的技術架構,而在於它的業務架構:12306根本就不應該在幾億中國人一票難求的情況下以窗口售票的模式在網上售票(零點開始出售若干天后的車票)。12306需要重構的不僅是它的技術架構,更重要的是它的業務架構:調整業務需求,換一種方式賣票,而不要去搞促銷秒殺這種噱頭式的遊戲。

後來證明12306確實是朝這個方向發展的:在售票方式上引入了排隊機制、整點售票調整爲分時段售票。其實如果能控制住併發訪問的量,很多棘手的技術問題也就不是什麼問題了。

2.大型網站架構模式

關於什麼是模式,這個來自建築學的詞彙是這樣定義的:“每一個模式描述了一個在我們周圍不斷重複發生的問題及該問題解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重複工作”。模式的關鍵在於模式的可重複性,問題與場景的可重複性帶來解決方案的可重複使用

2.1網站架構模式

1.分層

分層是企業應用系統中最常見的一種架構模式,將系統在橫向維度上切分成幾個部分,每個部分負責一部分相對比較單一的職責,然後通過上層對下層的依賴和調用組成一個完整的系統。

分層結構在計算機世界中無處不在,網絡的7層通信協議是一種分層結構;計算機硬件、操作系統、應用軟件也可以看作是一種分層結構。在大型網站架構中也採用分層結構,將網站軟件系統分爲1.應用層2.服務層3.數據層,如表:

但是分層架構也有一些挑戰,就是必須合理規劃層次邊界和接口,在開發過程中,嚴格遵循分層架構的約束,禁止跨層次的調用(應用層直接調用數據層)及逆向調用(數據層調用服務層,或者服務層調用應用層)。

2.分割

對軟件進行縱向切分

3.分佈式

對於大型網站,分層和分割的一個主要目的是爲了切分後的模塊便於分佈式部署,即將不同模塊部署在不同的服務器上,通過遠程調用協同工作。分佈式意味着可以使用更多的計算機完成同樣的功能,計算機越多,CPU、內存、存儲資源也就越多,能夠處理的併發訪問和數據量就越大,進而能夠爲更多的用戶提供服務。

在網站應用中,常用的分佈式方案有如下幾種:

1.分佈式應用和服務

將分層和分割後的應用和服務模塊分佈式部署,除了可以改善網站性能和併發性、加快開發和發佈速度、減少數據庫連接資源消耗外;還可以使不同應用複用共同的服務,便於業務功能擴展。

2.分佈式靜態資源

網站的靜態資源如JS, CSS, Logo圖片等資源獨立分佈式部署,並採用獨立的域名,即人們常說的動靜分離。靜態資源分佈式部署可以減輕應用服務器的負載壓力;通過使用獨立域名加快瀏覽器併發加載的速度;由負責用戶體驗的團隊進行開發維護有利於網站分工合作,使不同技術工種術業有專攻。

3.分佈式數據和存儲

大型網站需要處理以P爲單位的海量數據,單臺計算機無法提供如此大的存儲空間,這些數據需要分佈式存儲。除了對傳統的關係數據庫進行分佈式部署外,爲網站應用而生的各種NoSQL產品幾乎都是分佈式的。

4.分佈式計算

目前網站普遍使用Hadoop及其M apR educe分佈式計算框架進行此類批處理計算,其特點是移動計算而不是移動數據,將計算程序分發到數據所在的位置以加速計算和分佈式計算。

4.集羣

5.緩存

緩存就是將數據存放在距離計算最近的位置以加快處理速度。緩存是改善軟件性能的第一手段,現代CPU越來越快的一個重要因素就是使用了更多的緩存,在複雜的軟件設計中,緩存幾乎無處不在。大型網站架構設計在很多方面都使用了緩存設計。

使用緩存的例子:CDN,反向代理,本地緩存,分佈式緩存。

使用緩存有兩個前提條件

1.數據訪問熱點不均衡。
2.數據在某個時間段內有效,不會很快過期,否則緩存的數據就會因已經失效而產生髒讀,影響了結果的正確性。

6.異步

7.冗餘

8.自動化

9.安全

2.2架構模式在新浪微博中的應用

新浪微博的架構在較短的時間內幾經重構,最終形成了現在的架構:

系統分爲三個層次,最下層是基礎服務層,提供數據庫,緩存,存儲,搜索等數據服務,以及其他一些基礎技術服務,這些服務支撐了整個新浪微博的海量數據和高併發訪問,是整個系統的技術基礎。

中間層是平臺服務和應用服務層,新浪微博的核心服務是微博、關係和用戶,它們是新浪微博業務大廈的支柱。這些服務被分割爲獨立的服務模塊,通過依賴調用和共享基礎數據構成新浪微博的業務基礎。

最上層是API和新浪微博的業務層,各種客戶端(包括Web網站)和第三方應用,通過調用API集成到新浪微博的系統中,共同組成一個生態系統。

在新浪微博的早期架構中,微博發佈使用同步推模式,用戶發表微博後系統會立即將這條微博插入到數據庫所有粉絲的訂閱列表中,當用戶量比較大時,特別是明星用戶發佈微博時,會引起大量的數據庫寫操作,超出數據庫負載,系統性能急劇下降,用戶響應延遲加劇。後來新浪微博改用異步推拉結合的模式,用戶發表微博後系統將微博寫入消息隊列後立即返回,用戶響應迅速,消息隊列消費者任務將微博推送給所有當前在線粉絲的訂閱列表中,非在線用戶登錄後再根據關注列表拉取微博訂閱列表。

3.大型網站核心架構要素

關於什麼是架構,一種比較通俗的說法是“最高層次的規劃,難以改變的決定”,這些規劃和決定奠定了事物未來發展的方向和最終的藍圖。

3.1性能

性能是網站的一個重要指標,除非是沒得選擇(比如只能到www.12306.cn這一個網站上買火車票),否則用戶無法忍受一個響應緩慢的網站。一個打開緩慢的網站會導致嚴重的用戶流失,很多時候網站性能問題是網站架構升級優化的觸發器。可以說性能是網站架構設計的一個重要方面,任何軟件架構設計方案都必須考慮可能會帶來的性能問題。

也正是因爲性能問題幾乎無處不在,所以優化網站性能的手段也非常多,從用戶瀏覽器到數據庫,影響用戶請求的所有環節都可以進行性能優化。

瀏覽器端,可以通過瀏覽器緩存、使用頁面壓縮、合理佈局頁面、減少Cookie傳輸等手段改善性能。

還可以使用CDN,將網站靜態內容分發至離用戶最近的網絡服務商機房,使用戶通過最短訪問路徑獲取數據。可以在網站機房部署反向代理服務器,緩存熱點文件,加快請求響應速度,減輕應用服務器負載壓力。

應用服務器端,可以使用服務器本地緩存和分佈式緩存,通過緩存在內存中的熱點數據處理用戶請求,加快請求處理過程,減輕數據庫負載壓力。

也可以通過異步操作將用戶請求發送至消息隊列等待後續任務處理,而當前請求直接返回響應給用戶。

在網站有很多用戶高併發請求的情況下,可以將多臺應用服務器組成一個集羣共同對外服務,提高整體處理能力,改善性能。

代碼層面,也可以通過使用多線程、改善內存管理等手段優化性能。

在數據庫服務器端,索引、緩存、SQL優化等性能優化手段都已經比較成熟。而方興未艾的NoSQL數據庫通過優化數據模型、存儲結構、伸縮特性等手段在性能方面的優勢也日趨明顯。

衡量網站性能有一系列指標,重要的有響應時間TPS系統性能計數器等,通過測試這些指標以確定系統設計是否達到目標。這些指標也是網站監控的重要參數,通過監控這些指標可以分析系統瓶頸,預測網站容量,並對異常指標進行報警,保障系統可用性。

3.2可用性

網站高可用的主要手段是冗餘,應用部署在多臺服務器上同時提供訪問,數據存儲在多臺服務器上互相備份,任何一臺服務器宕機都不會影響應用的整體可用,也不會導致數據丟失。

對於應用服務器而言,多臺應用服務器通過負載均衡設備組成一個集羣共同對外提供服務,任何一臺服務器宕機,只需把請求切換到其他服務器就可實現應用的高可用,但是一個前提條件是應用服務器上不能保存請求的會話信息。否則服務器宕機,會話丟失,即使將用戶請求轉發到其他服務器上也無法完成業務處理

3.3伸縮性

衡量架構伸縮性的主要標準就是是否可以用多臺服務器構建集羣,是否容易向集羣中添加新的服務器。加入新的服務器後是否可以提供和原來的服務器無差別的服務。集羣中可容納的總的服務器數量是否有限制。

3.4擴展性

不同於其他架構要素主要關注非功能性需求,網站的擴展性架構直接關注網站的功能需求。網站快速發展,功能不斷擴展,如何設計網站的架構使其能夠快速響應需求變化,是網站可擴展架構主要的目的。

網站可伸縮架構的主要手段是事件驅動架構分佈式服務

事件驅動架構在網站通常利用消息隊列實現,將用戶請求和其他業務事件構造成消息發佈到消息隊列,消息的處理者作爲消費者從消息隊列中獲取消息進行處理。通過這種方式將消息產生和消息處理分離開來,可以透明地增加新的消息生產者任務或者新的消息消費者任務。

分佈式服務則是將業務和可複用服務分離開來,通過分佈式服務框架調用。新增產品可以通過調用可複用的服務實現自身的業務邏輯,而對現有產品沒有任何影響。可複用服務升級變更的時候,也可以通過提供多版本服務對應用實現透明升級,不需要強制應用同步變更。

3.5安全性

3.6小結

性能可用性伸縮性擴展性安全性是網站架構最核心的幾個要素。

第二篇:架構

4.瞬時響應:網站的高性能架構

網站性能是客觀的指標,可以具體體現到響應時間、吞吐量等技術指標,同時也是主觀的感受,而感受則是一種與具體參與者相關的微妙的東西,用戶的感受和工程師的感受不同,不同的用戶感受也不同。

2.性能測試指標

主要指標有響應時間,併發數,吞吐量,性能計數器等:

1.響應時間

指應用執行一個操作需要的時間,包括從發出請求開始收到最後響應數據所需要的時間。響應時間是系統最重要的性能指標,直觀地反映了系統的“快慢”。

2.併發數

指系統能夠同時處理請求的數目,這個數字也反映了系統的負載特性。

注意釐清數量關係

網站系統用戶數>>網站在線用戶數>>網站併發用戶數

3.吞吐量

指單位時間內系統處理的請求數量,體現了系統的整體處理能力。TPS(每秒事務數)是吞吐量的一個常用量化指標,此外還有HPS(每秒HTTP請求數)、QPS(每秒查詢數)等。

系統吞吐量系統併發數,以及響應時間的關係可以形象地理解爲高速公路的通行狀況:

吞吐量是每天通過收費站的車輛數目(可以換算成收費站收取的高速費),併發數是高速公路上的正在行駛的車輛數目,響應時間是車速。

車輛很少時,車速很快,但是收到的高速費也相應較少;隨着高速公路上車輛數目的增多,車速略受影響,但是收到的高速費增加很快;隨着車輛的繼續增加,車速變得越來越慢,高速公路越來越堵,收費不增反降;如果車流量繼續增加,超過某個極限後,任何偶然因素都會導致高速全部癱瘓,車走不動,費當然也收不着,而高速公路成了停車場(資源耗盡)。

4.性能計數器

System Load即系統負載,指當前正在被CPU執行和等待被CPU執行的進程數目總和,是反映系統忙閒程度的重要指標。多核CPU的情況下,完美情況是所有CPU都在使用,沒有進程在等待處理,所以Load的理想值是CPU的數目。當Load值低於CPU數目的時候,表示CPU有空閒,資源存在浪費;當Load值高於CPU數目的時候,表示進程在排隊等待CPU調度,表示系統資源不足,影響應用程序的執行性能。在Linux系統中使用top命令查看,該值是三個浮點數,表示最近1分鐘,10分鐘,15分鐘的運行隊列平均進程數。

3.性能測試方法

性能測試是一個總稱,具體可以細分爲性能測試負載測試壓力測試穩定性測試

4.性能優化方法

定位產生性能問題的具體原因後,就需要進行性能優化,根據網站分層架構,可分爲1.Web前端性能優化2.應用服務器性能優化、**3.存儲服務器性能優化**3大類。

4.2Web前端性能優化

1.瀏覽器訪問優化

1.減少http請求

HTTP協議是無狀態的應用層協議,意味着每次HTTP請求都需要建立通信鏈路、進行數據傳輸,而在服務器端,每個HTTP都需要啓動獨立的線程去處理。這些通信和服務的開銷都很昂貴,減少HTTP請求的數目可有效提高訪問性能。

減少HTTP的主要手段是合併CSS、合併JavaScript、合併圖片。將瀏覽器一次訪問需要的JavaScript、CSS合併成一個文件,這樣瀏覽器就只需要一次請求。圖片也可以合併,多張圖片合併成一張,如果每張圖片都有不同的超鏈接,可通過CSS偏移響應鼠標點擊操作,構造不同的URL。

2.使用瀏覽器緩存

對於一個網站而言,CSS,JS,logo,圖標這些靜態資源文件更新的頻率都比較低,而這些文件又幾乎是每次HTTP請求都需要的,如果將這些文件緩存在瀏覽器中,可以極好地改善性能。通過設置HTTP頭中的Cache-Control和Expires的屬性,可設定瀏覽器緩存,緩存時間可以是數天,甚至是幾個月

3.啓用壓縮

4.CSS放在頁面最上面,JS放在頁面最下面

5.減少Cookie傳輸

一方面,Cookie包含在每次請求和響應中,太大的C ookie會嚴重影響數據傳輸,因此哪些數據需要寫入C ookie需要慎重考慮,儘量減少C ookie中傳輸的數據量。另一方面,對於某些靜態資源的訪問,如CSS、Script等,發送C ookie沒有意義,可以考慮靜態資源使用獨立域名訪問,避免請求靜態資源時發送C ookie,減少C ookie傳輸的次數

2.CDN加速

CDN能夠緩存的一般是靜態資源,如圖片、文件、CSS、Script腳本、靜態網頁等,但是這些文件訪問頻度很高,將其緩存在CDN可極大改善網頁的打開速度。

3.反向代理

4.3應用服務器性能優化

應用服務器就是處理網站業務的服務器,網站的業務代碼都部署在這裏,是網站開發最複雜,變化最多的地方,優化手段主要是緩存,集羣,異步等。

1.分佈式緩存

緩存的基本原理

緩存指將數據存儲在相對較高訪問速度的存儲介質中,以供系統處理。一方面緩存訪問速度快,可以減少數據訪問的時間,另一方面如果緩存的數據是經過計算處理得到的,那麼被緩存的數據無需重複計算即可直接使用,因此緩存還起到減少計算時間的作用。

不合理使用緩存的例子:

1.頻繁修改的數據

一般來說,數據的讀寫比在2:1以上,即寫入一次緩存,在數據更新前至少讀取兩次,緩存纔有意義。在實踐中,這個比例通常非常高,例如新浪熱門微博,緩存以後可能會被讀取數百萬次。

2.沒有熱點的訪問

3.數據不一致與髒讀

一般會對緩存的數據設置失效時間,一旦超過失效時間,就要從數據庫中重新加載。因此應用要容忍一定時間的數據不一致,如賣家已經編輯了商品屬性,但是需要過一段時間才能被買家看到。在互聯網應用中,這種延遲通常是可以接受的,但是具體應用仍需慎重對待。還有一種策略是數據更新時立即更新緩存,不過這也會帶來更多系統開銷和事務一致性的問題。

4.緩存可用性

通過分佈式緩存服務器集羣,將緩存數據分佈到集羣多臺服務器上可在一定程度上改善緩存的可用性。當一臺緩存服務器宕機的時候,只有部分緩存數據丟失,重新從數據庫加載這部分數據不會對數據庫產生很大影響。

5.緩存預熱

緩存中存放的是熱點數據,熱點數據又是緩存系統利用LRU(最近最久未用算法)對不斷訪問的數據篩選淘汰出來的,這個過程需要花費較長的時間。新啓動的緩存系統如果沒有任何數據,在重建緩存數據的過程中,系統的性能和數據庫負載都不太好,那麼最好在緩存系統啓動時就把熱點數據加載好,這個緩存預加載手段叫作緩存預熱(warm up)。對於一些元數據如城市地名列表、類目信息,可以在啓動時加載數據庫中全部數據到緩存進行預熱

6.緩存穿透

如果因爲不恰當的業務、或者惡意攻擊持續高併發地請求某個不存在的數據,由於緩存沒有保存該數據,所有的請求都會落到數據庫上,會對數據庫造成很大壓力,甚至崩潰。一個簡單的對策是將不存在的數據也緩存起來(其value值爲null)

分佈式緩存架構

分佈式緩存指緩存部署在多個服務器組成的集羣中,以集羣方式提供緩存服務,其架構方式有兩種,一種是以JBoss C ache爲代表的需要更新同步的分佈式緩存一種是以Memcached爲代表的不互相通信的分佈式緩存

Memcached

2.異步操作

需要注意的是,由於數據寫入消息隊列後立即返回給用戶,數據在後續的業務校驗、寫數據庫等操作可能失敗,因此在使用消息隊列進行業務異步處理後,需要適當修改業務流程進行配合,如訂單提交後,訂單數據寫入消息隊列,不能立即返回用戶訂單提交成功,需要在消息隊列的訂單消費者進程真正處理完該訂單,甚至商品出庫後,再通過電子郵件或SM S消息通知用戶訂單成功,以免交易糾紛。

任何可以晚點做的事情都應該晚點再做。保證數據的正確性

3.使用集羣

4.代碼優化

1.多線程

從資源利用的角度看,使用多線程的原因主要有兩個:IO阻塞與多CPU

網站的應用程序一般都被Web服務器容器管理,用戶請求的多線程也通常被Web服務器容器管理,但不管是Web容器管理的線程,還是應用程序自己創建的線程,一臺服務器上啓動多少線程合適呢?

假設服務器上執行的都是相同類型任務,針對該類任務啓動的線程數有個簡化的估算公式可供參考:

啓動線程數=[任務執行時間/(任務執行時間×IO等待時間)]×CPU內核數

最佳啓動線程數和CPU內核數量成正比,和IO阻塞時間成反比。如果任務都是CPU計算型任務,那麼線程數最多不超過CPU內核數,因爲啓動再多線程,CPU也來不及調度相反如果是任務需要等待磁盤操作,網絡響應,那麼多啓動線程有助於提高任務併發度,提高系統吞吐能力,改善系統性能。(看是CPU計算型還是磁盤操作!)

多線程需要注意線程安全的問題,這也是缺乏經驗的網站工程師最容易犯錯的地方,而線程安全B ug又難以測試和重現,網站故障中,許多所謂偶然發生的“靈異事件”都和多線程併發問題有關。對網站而言,不管有沒有進行多線程編程,工程師寫的每一行代碼都會被多線程執行,因爲用戶請求是併發提交的,也就是說,所有的資源——對象、內存、文件、數據庫,乃至另一個線程都可能被多線程併發訪問。

2.資源複用

系統運行時,要儘量減少那些開銷很大的系統資源的創建和銷燬,比如數據庫連接、網絡通信連接、線程、複雜對象等。從編程角度,資源複用主要有兩種模式:單例(Singleton)對象池(Object Pool)

單例雖然是GoF經典設計模式中較多被詬病的一個模式,但由於目前Web開發中主要使用貧血模式,從Service到D ao都是些無狀態對象,無需重複創建,使用單例模式也就自然而然了。事實上,Java開發常用的對象容器Spring默認構造的對象都是單例(需要注意的是Spring的單例是Spring容器管理的單例,而不是用單例模式構造的單例)。

前面說過,對於每個Web請求(HTTP Request), Web應用服務器都需要創建一個獨立的線程去處理,這方面,應用服務器也採用線程池(Thread Pool)的方式。這些所謂的連接池、線程池,本質上都是對象池,即連接、線程都是對象,池管理方式也基本相同

4.4存儲性能優化

1.機械硬盤VS固態硬盤

機械硬盤是目前最常用的一種硬盤,通過馬達驅動磁頭臂,帶動磁頭到指定的磁盤位置訪問數據,由於每次訪問數據都需要移動磁頭臂,因此機械硬盤在數據連續訪問(要訪問的數據存儲在連續的磁盤空間上)和隨機訪問(要訪問的數據存儲在不連續的磁盤空間)時,由於移動磁頭臂的次數相差巨大,性能表現差別也非常大

2.B+樹.VS.LSM樹

本書前面提到,由於傳統的機械磁盤具有快速順序讀寫、慢速隨機讀寫的訪問特性,這個特性對磁盤存儲結構和算法的選擇影響甚大。

通常會對數據排序後存儲,加快數據檢索速度,這就需要保證數據在不斷更新、插入、刪除後依然有序,傳統關係數據庫的做法是使用B+樹

目前許多NoSQL產品採用LSM樹作爲主要數據結構。

3.RAID.VS.HDFS

RAID技術可以通過硬件實現,比如專用的RAID卡或者主板直接支持,也可以通過軟件實現。RAID技術在傳統關係數據庫及文件系統中應用比較廣泛,但是在大型網站比較喜歡使用的NoSQL,以及分佈式文件系統中,RAID技術卻遭到冷落。

現在一般用HDFS,HDFS配合M apR educe等並行計算框架進行大數據處理時,可以在整個集羣上併發讀寫訪問所有的磁盤,無需RAID支持。

5.萬無一失:網站的高可用架構

5.1網站可用性的度量與考覈

網站的頁面能完整呈現在最終用戶面前,需要經過很多個環節,任何一個環節出了問題,都可能導致網站頁面不可訪問。DNS會被劫持、CDN服務可能會掛掉、網站服務器可能會宕機、網絡交換機可能會失效、硬盤會損壞、網卡會鬆掉、甚至機房會停電、空調會失靈、程序會有B ug、黑客會攻擊、促銷會引來大量訪問、第三方合作伙伴的服務會不可用……要保證一個網站永遠完全可用幾乎是一件不可能完成的使命。

一個典型的網站設計通常遵循如圖所示的基本分層架構模型。

典型的分層模型是三層,即應用層、服務層、數據層;各層之間具有相對獨立性,應用層主要負責具體業務邏輯處理服務層負責提供可複用的服務數據層負責數據的存儲與訪問。中小型網站在具體部署時,通常將應用層和服務層部署在一起,而數據層則另外部署,如圖5.3所示(事實上,這也是網站架構演化的第一步)。

在複雜的大型網站架構中,劃分的粒度會更小,更詳細,結構更加複雜,但通常還是可以將服務器劃分到這三層中。

應用層

位於應用層的服務器通常爲了應對高併發的訪問請求,會通過負載均衡設備將一組服務器組成一個集羣共同對外提供服務,當負載均衡設備通過心跳檢測等手段監控到某臺應用服務器不可用時,就將其從集羣列表中剔除,並將請求分發到集羣中其他可用的服務器上,使整個集羣保持可用,從而實現應用高可用。

服務層

位於服務層的服務器情況和應用層的服務器類似,也是通過集羣方式實現高可用,只是這些服務器被應用層通過分佈式服務調用框架訪問,分佈式服務調用框架會在應用層客戶端程序中實現軟件負載均衡,並通過服務註冊中心對提供服務的服務器進行心跳檢測,發現有服務不可用,立即通知客戶端程序修改服務訪問列表,剔除不可用的服務器。

數據層

位於數據層的服務器情況比較特殊,數據服務器上存儲着數據,爲了保證服務器宕機時數據不丟失,數據訪問服務不中斷,需要在數據寫入時進行數據同步複製,將數據寫入多臺服務器上,實現數據冗餘備份。當數據服務器宕機時,應用程序將訪問切換到有備份數據的服務器上。

5.3高可用的應用

應用層主要處理網站應用的業務邏輯,因此有時也稱作業務邏輯層,應用的一個顯著特點是應用的無狀態性

所謂無狀態的應用是指應用服務器不保存業務的上下文信息,而僅根據每次請求提交的數據進行相應的業務邏輯處理,多個服務實例(服務器)之間完全對等,請求提交到任意服務器,處理結果都是完全一樣的

1.通過負載均衡進行無狀態服務的失效轉移

2.應用服務器集羣的Session管理

應用服務器的高可用架構設計主要基於服務無狀態這一特性,但是事實上,業務總是有狀態的,在交易類的電子商務網站,需要有購物車記錄用戶的購買信息,用戶每次購買請求都是向購物車中增加商品;在社交類的網站中,需要記錄用戶的當前登錄狀態、最新發布的消息及好友狀態等,用戶每次刷新頁面都需要更新這些信息。

Web應用中將這些多次請求修改使用的上下文對象稱作會話(Session),單機情況下,Session可由部署在服務器上的Web容器(如JBoss)管理。在使用負載均衡的集羣環境中,由於負載均衡服務器可能會將請求分發到集羣任何一臺應用服務器上,所以保證每次請求依然能夠獲得正確的Session比單機時要複雜很多

集羣環境下,Session管理主要有以下幾種手段。

1.Session複製

原理很簡單,在集羣中的幾臺服務器之間同步Session對象,使得每臺服務器上都保存有用戶的Session信息,這樣任何一臺服務器宕機,都可以在其他服務器上找到Session。

缺點是,大量用戶訪問的情況下,會出現服務器內存不夠Session使用的情況。

而大型網站的核心應用集羣就是數千臺服務器,同時在線用戶可達千萬,因此並不適用這種方案。

2.Session綁定

Session綁定可以利用負載均衡的源地址Hash算法實現,負載均衡服務器總是將來自同一IP的請求分發到同一臺服務器上,這種方法又被稱作爲會話粘滯

但Session綁定的方案不符合我們的要求,如果一臺服務器宕機,那麼該服務器上的Session將不存在,用戶請求切換後無法完成業務。

因此雖然大部分負載均衡服務器都提供源地址負載均衡算法,但很少有網站利用這個算法進行Session管理。

3.利用Cookie記錄Session

利用Cookie記錄Session也有缺點,比如受Cookie大小限制,能記錄的信息有限,每次請求響應都需要傳輸Cookie,影響性能;如果用戶關閉C ookie,訪問就會不正常。但是由於C ookie的簡單易用,可用性高,支持應用服務器的線性伸縮,而大部分應用需要記錄的Session信息又比較小。因此事實上,許多網站都或多或少地使用C ookie記錄Session

4.Session服務器

那麼有沒有可用性高、伸縮性好、性能也不錯,對信息大小又沒有限制的服務器集羣Session管理方案呢?

答案就是Session服務器。利用獨立部署的Session服務器(集羣)統一管理S ession,應用服務器每次讀寫Session時,都訪問Session服務器,如圖所示。

這種解決方案事實上是將應用服務器的狀態分離分爲無狀態的應用服務器和有狀態的Session服務器,然後針對這兩種服務器的不同特性分別設計其架構。

對於有狀態的Session服務器,一種比較簡單的方法是利用分佈式緩存、數據庫等,在這些產品的基礎上進行包裝,使其符合Session的存儲和訪問要求。如果業務場景對Session管理有比較高的要求,比如利用Session服務集成單點登錄(SSO)、用戶服務等功能,則需要開發專門的Session服務管理平臺。

5.4高可用的服務

5.5高可用的數據

保證數據存儲高可用的手段主要是1.數據備份和2.失效轉移機制。數據備份是保證數據有多個副本,任意副本的失效都不會導致數據的永久丟失,從而實現數據完全的持久化。而失效轉移機制則保證當一個數據副本不可訪問時,可以快速切換訪問數據的其他副本,保證系統可用。

關於緩存服務的高可用,在實踐中爭議很大,一種觀點認爲緩存已經成爲網站數據服務的重要組成部分,事實上承擔了業務中絕大多數的數據讀取訪問服務,緩存服務失效可能會導致數據庫負載過高而宕機,進而影響整個網站的可用性,因此緩存服務需要實現和數據存儲服務同樣的高可用。

另一種觀點認爲,緩存服務不是數據存儲服務,緩存服務器宕機引起緩存數據丟失導致服務器負載壓力過高應該通過其他手段解決,而不是提高緩存服務本身的高可用。

筆者持後一種觀點,對於緩存服務器集羣中的單機宕機,如果緩存服務器集羣規模較大,那麼單機宕機引起的緩存數據丟失比例和數據庫負載壓力變化都較小,對整個系統影響也較小。擴大緩存服務器集羣規模的一個簡單手段就是整個網站共享同一個分佈式緩存集羣,單獨的應用和產品不需要部署自己的緩存服務器,只需要向共享緩存集羣申請緩存資源即可。並且通過邏輯或物理分區的方式將每個應用的緩存部署在多臺服務器上,任何一臺服務器宕機引起的緩存失效都隻影響應用緩存數據的一小部分,不會對應用性能和數據庫負載造成太大影響。

C AP原理

在討論高可用數據服務架構之前,必須先討論的一個話題是,爲了保證數據的高可用,網站通常會犧牲另一個也很重要的指標:數據一致性。也就是說,數據的高可用性跟數據的一致性不可兼得。

高可用的數據有如下幾個層面的含義。

1.數據持久性

2.數據的可訪問性

3.數據一致性

CAP原理認爲,一個提供數據服務的存儲系統無法同時滿足數據一致性(C onsistency)、數據可用性(A vailib ility)、分區耐受性(Patition Tolerance,系統具有跨網絡分區的伸縮性)這三個條件,如圖。

在大型網站中,通常會選擇強化分佈式存儲系統的可用性(A)和伸縮性(P),而在某種程度上放棄一致性(C)。

數據一致性可以分爲如下幾點:

1.數據強一致

各個副本的數據在物理存儲中總是一致的,數據更新操作結果和操作響應總是一致的,即操作響應通知更新失敗,那麼數據一定沒有被更新,而不是處於不確定狀態。

2.數據用戶一致

數據在物理存儲中的各個副本的數據可能是不一致的,但是終端用戶訪問時,通過糾錯和校驗機制,可以確定一個一致的且正確的數據返回給用戶。

3.數據最終一致

這是數據一致性中較弱的一種,即物理存儲的數據可能是不一致的,終端用戶訪問到的數據可能也是不一致的(同一用戶連續訪問,結果不同;或者不同用戶同時訪問,結果不同),但系統經過一段時間(通常是一個比較短的時間段)的自我恢復和修正,數據最終會達到一致

關係數據庫熱備機制就是通常所說的M aster-S lave同步機制。M aster-S lave機制不但解決了數據備份問題,還改善了數據庫系統的性能,實踐中,通常使用讀寫分離的方法訪問S lave和M aster數據庫,寫操作只訪問M aster數據庫,讀操作只訪問S lave數據庫

關於數據的失效轉移:

失效轉移操作主要由三部分組成:1.失效確認,2.失效轉移,3.數據恢復

1.失效確認

判斷服務器宕機是系統進行失效轉移的第一步,系統確認一臺服務器是否宕機的手段有兩種:1.心跳檢測2.應用程序訪問失敗報告,如圖。

2.訪問轉移

3.數據恢復

網站發佈的流程:

網站發佈畢竟是一次提前預知的服務器宕機,所以過程可以更柔和,對用戶影響更小。通常使用發佈腳本來完成發佈,其流程如圖。

目前大部分網站都採用Web自動化測試技術,使用自動測試工具或腳本完成測試。比較流行的Web自動化測試工具是ThoughtW orks開發的SeleniumSelenium運行在瀏覽器中,模擬用戶操作進行測試,因此Selenium可以同時完成Web功能測試和瀏覽器兼容測試

在網站發佈時,並不是把測試通過的代碼包直接發佈到線上服務器,而是先發布到預發佈機器上,開發工程師和測試工程師在預發佈服務器上進行預發佈驗證,執行一些典型的業務流程,確認系統沒有問題後才正式發佈。

5.7網站運行監控

6.永無止境:網站的伸縮性架構

所謂網站的伸縮性是指不需要改變網站的軟硬件設計,僅僅通過改變部署服務器數量就可以擴大或者縮小網站的服務處理能力。

回顧網站架構發展歷程, 網站架構發展史就是一部不斷向網站添加服務器的歷史。只要工程師能向網站的服務器集羣中添加新的機器,只要新添加的服務器能線性提高網站的整體服務處理能力,網站就無需爲不斷增長的用戶和訪問而焦慮。

6.2應用服務器集羣的伸縮性設計

實現負載均衡的主要算法

1.HTTP重定向負載均衡

這種負載均衡方案的優點是比較簡單缺點是瀏覽器需要兩次請求服務器才能完成一次訪問,性能較差;重定向服務器自身的處理能力有可能成爲瓶頸,整個集羣的伸縮性規模有限;使用HTTP302響應碼重定向,有可能使搜索引擎判斷爲SEO作弊,降低搜索排名。因此實踐中使用這種方案進行負載均衡的案例並不多見

2.DNS域名解析負載均衡

在DNS服務器中配置多個A記錄,如:www.m ysite.com IN A 114.100.80.1、www.m ysite.com IN A 114.100.80.2、www.m ysite.com IN A 114.100.80.3。
每次域名解析請求都會根據負載均衡算法計算一個不同的IP地址返回,這樣A記錄中配置的多個服務器就構成一個集羣,並可以實現負載均衡。

DNS域名解析負載均衡的優點是將負載均衡的工作轉交給DNS,省掉了網站管理維護負載均衡服務器的麻煩,同時許多DNS還支持基於地理位置的域名解析,即會將域名解析成距離用戶地理最近的一個服務器地址,這樣可加快用戶訪問速度,改善性能。但是DNS域名解析負載均衡也有缺點,就是1.目前的DNS是多級解析,每一級DNS都可能緩存A記錄,當下線某臺服務器後,即使修改了DNS的A記錄,要使其生效也需要較長時間,這段時間,DNS依然會將域名解析到已經下線的服務器,導致用戶訪問失敗;而且2.DNS負載均衡的控制權在域名服務商那裏,網站無法對其做更多改善和更強大的管理。

事實上,大型網站總是部分使用DNS域名解析,利用域名解析作爲第一級負載均衡手段,即域名解析得到的一組服務器並不是實際提供Web服務的物理服務器,而是同樣提供負載均衡服務的內部服務器,這組內部負載均衡服務器再進行負載均衡,將請求分發到真實的Web服務器上

大型網站利用DNS域名解析作爲第一級的負載均衡手段。

3.反向代理負載均衡

前面我們提到利用反向代理緩存資源,以改善網站性能。實際上,在部署位置上,反向代理服務器處於Web服務器前面(這樣纔可能緩存Web響應,加速訪問),這個位置也正好是負載均衡服務器的位置,所以大多數反向代理服務器同時提供負載均衡的功能,管理一組Web服務器,將請求根據負載均衡算法轉發到不同Web服務器上。Web服務器處理完成的響應也需要通過反向代理服務器返回給用戶。由於Web服務器不直接對外提供訪問,因此Web服務器不需要使用外部IP地址,而反向代理服務器則需要配置雙網卡和內部外部兩套IP地址

由於反向代理服務器轉發請求在HTTP協議層面,因此也叫應用層負載均衡其優點是和反向代理服務器功能集成在一起,部署簡單缺點是反向代理服務器是所有請求和響應的中轉站,其性能可能會成爲瓶頸

4.IP負載均衡

在網絡層通過修改目標地址進行負載均衡。

5.數據鏈路層負載均衡

顧名思義,數據鏈路層負載均衡是指在通信協議的數據鏈路層修改mac地址進行負載均衡。

這種數據傳輸方式又稱作三角傳輸模式負載均衡數據分發過程中不修改IP地址,只修改目的m ac地址,通過配置真實物理服務器集羣所有機器虛擬IP和負載均衡服務器IP地址一致,從而達到不修改數據包的源地址和目的地址就可以進行數據分發的目的,由於實際處理請求的真實物理服務器IP和數據請求目的IP一致,不需要通過負載均衡服務器進行地址轉換,可將響應數據包直接返回給用戶瀏覽器,避免負載均衡服務器網卡帶寬成爲瓶頸。這種負載均衡方式又稱作直接路由方式(DR)。

使用三角傳輸模式的鏈路層負載均衡是目前大型網站使用最廣的一種負載均衡手段。在Linux平臺上最好的鏈路層負載均衡開源產品是LVS(Linux V irtual Server)。

6.負載均衡算法

負載均衡服務器的實現分成兩個部分:

1.根據負載均衡算法和Web服務器列表計算得到集羣中一臺Web服務器的地址。
2.將請求數據發送到該地址對應的Web服務器上。

前面描述瞭如何將請求數據發送到Web服務器上,而具體的負載均衡算法通常有如下幾種:

1.輪詢(RR)
2.加權輪詢(WRR)
3.隨機(Random)

4.最少連接(Least Connections)
記錄每個應用服務器正在處理的連接數(請求數),將新到的請求分發到最少連接的服務器上,應該說,這是最符合負載均衡定義的算法。同樣,最小連接算法也可以實現加權最少連接。

5.源地址散列(Source Hashing)

6.3分佈式緩存集羣的伸縮性設計

我們在本書第4章討論過分佈式緩存,不同於應用服務器集羣的伸縮性設計,分佈式緩存集羣的伸縮性不能使用簡單的負載均衡手段來實現。

必須讓新上線的緩存服務器對整個分佈式緩存集羣影響最小,也就是說新加入緩存服務器後應使整個緩存服務器集羣中已經緩存的數據儘可能還被訪問到,這是分佈式緩存集羣伸縮性設計的最主要目標。

1.Memcached分佈式緩存集羣的訪問模型

如果使用樸素的Hash路由算法,將會出現問題。本來加入新的緩存服務器是爲了降低數據庫的負載壓力,但是操作不當卻導致了數據庫的崩潰。如果不對問題和解決方案有透徹瞭解,網站技術總有想不到的陷阱讓架構師一腳踩空。遇到這種情況,用某網站一位資深架構師的話說,就是“一股寒氣從腳底板竄到了腦門心”。

能不能通過改進路由算法,使得新加入的服務器不影響大部分緩存數據的正確命中呢?目前比較流行的算法是一致性Hash算法

一致性Hash算法也有小問題。

計算機領域有句話:計算機的任何問題都可以通過增加一個虛擬層來解決。計算機硬件、計算機網絡、計算機軟件都莫不如此。計算機網絡的7層協議,每一層都可以看作是下一層的虛擬層;計算機操作系統可以看作是計算機硬件的虛擬層;Java虛擬機可以看作是操作系統的虛擬層;分層的計算機軟件架構事實上也是利用虛擬層的概念。

解決上述一致性Hash算法帶來的負載不均衡問題,也可以通過使用虛擬層的手段:將每臺物理緩存服務器虛擬爲一組虛擬緩存服務器,將虛擬服務器的Hash值放置在Hash環上,KEY在環上先找到虛擬服務器節點,再得到物理服務器的信息。

6.4數據存儲服務器集羣的伸縮性設計

1.關係性數據庫集羣的伸縮性設計

目前網站在線業務應用中比較成熟的支持數據分片的分佈式關係數據庫產品主要有Cobar。其架構圖如下。

Cobar系統組件模型如圖。

前端通信模塊負責和應用程序通信,接收到SQL請求(select * from users where userid in (12,22,23))後轉交給SQL解析模塊,SQL解析模塊解析獲得SQL中的路由規則查詢條件(userid in(12,22,23))再轉交給SQL路由模塊,SQL路由模塊根據路由規則配置(userid爲偶數路由至數據庫A, userid爲奇數路由至數據庫B)將應用程序提交的SQL分解成兩條SQ L(select * from users w here userid in (12,22);select * from users w here userid in (23);)轉交給SQL執行代理模塊,發送至數據庫A和數據庫B分別執行。

數據庫A和數據庫B的執行結果返回至SQL執行模塊,通過結果合併模塊將兩個返回結果集合併成一個結果集,最終返回給應用程序,完成在分佈式數據庫中的一次訪問請求。

那麼Cobar如何做集羣的伸縮呢?
Cobar的伸縮有兩種:1.Cobar服務器集羣的伸縮2.MySQL服務器集羣的伸縮

2.NoSQL數據庫的伸縮性設計

大型網站遇到了關係數據庫難以克服的缺陷——糟糕的海量數據處理能力及僵硬的設計約束,局面纔有所改善。爲了解決上述問題,NoSQL這一概念被提了出來,以彌補關係數據庫的不足。

NoSQL,主要指非關係的、分佈式的數據庫設計模式。也有許多專家將NoSQL解讀爲N ot O nly SQ L,表示NoSQL只是關係數據庫的補充,而不是替代方案。一般而言,NoSQL數據庫產品都放棄了關係數據庫的兩大重要基礎:以關係代數爲基礎的結構化查詢語言(SQL)和事務一致性保證(ACID)。而強化其他一些大型網站更關注的特性:高可用性和可伸縮性

開源社區有各種N oSQL產品,其支持的數據結構和伸縮特性也各不相同,目前看來,應用最廣泛的是Apache HBase

6.5小結

高手定律

這個世界只有遇不到的問題,沒有解決不了的問題,高手之所以成爲高手,是因爲他們遇到了常人很難遇到的問題,並解決了。所以百度有很多廣告搜索的高手,淘寶有很多海量數據的高手,Q Q有很多高併發業務的高手,原因大抵如此。一個100萬用戶的網站,不會遇到1億用戶同時在線的問題;一個擁有100萬件商品網站的工程師,可能無法理解一個擁有10億件商品網站的架構。

救世主定律

遇到問題,分析問題,最後總能解決問題。如果遇到問題就急匆匆地從外面挖一個高手,然後指望高手如探囊取物般輕鬆搞定,最後怕是隻有彼此抱怨和傷害。許多問題只是看起來一樣,具體問題總是要具體對待的,沒有銀彈,沒有救世主。所以這個定律準確地說應該是“沒有救世主定律”。

7.按需應變:網站的可擴展架構

網站擴展性架構設計:對現有系統影響最小的情況下,系統功能可持續擴展及提升的能力。

首先釐清容易混淆的兩個概念:

1.擴展性(Extensibility):

指對現有系統影響最小的情況下,系統功能可持續擴展或提升的能力。表現在系統基礎設施穩定不需要經常變更,應用之間較少依賴和耦合,對需求變更可以敏捷響應。它是系統架構設計層面的開閉原則(對擴展開放,對修改關閉),架構設計考慮未來功能擴展,當系統增加新功能時,不需要對現有系統的結構和代碼進行修改。

2.伸縮性(Scalability):

指系統能夠通過增加(減少)自身資源規模的方式增強(減少)自己計算處理事務的能力。如果這種增減是成比例的,就被稱作線性伸縮性。在網站架構中,通常指利用集羣的方式增加服務器數量、提高系統的整體事務吞吐能力。

7.2利用分佈式消息隊列降低系統耦合性

如果模塊之間不存在直接調用,那麼新增模塊或者修改模塊就對其他模塊影響最小,這樣系統的可擴展性無疑更好一些。

1.事件驅動架構

事件驅動架構(Event Driven Architecture):通過在低耦合的模塊之間傳輸事件消息,以保持模塊的鬆散耦合,並藉助事件消息的通信完成模塊間合作,典型的EDA架構就是操作系統中常見的生產者消費者模式。在大型網站架構中,具體實現手段有很多,最常用的是分佈式消息隊列,如圖所示。

2.分佈式消息隊列

目前開源的和商業的分佈式消息隊列產品有很多,比較著名的如Apache ActiveMQ等,這些產品除了實現分佈式消息隊列的一般功能,在可用性、伸縮性、數據一致性、性能和可管理性方面也做了很多改善。

7.3利用分佈式服務打造可複用的業務平臺

巨無霸的應用系統會帶來很多問題:
1.編譯,部署困難
2.代碼分支管理困難
3.數據庫連接耗盡
4.新增業務困難

解決方案就是拆分,將模塊獨立部署,降低系統耦合性。拆分可以分爲縱向拆分和橫向拆分兩種。

縱向拆分:將一個大應用拆分爲多個小應用,如果新增業務較爲獨立,那麼就直接將其設計部署爲一個獨立的Web應用系統。

橫向拆分:將複用的業務拆分出來,獨立部署爲分佈式服務,新增業務只需要調用這些分佈式服務,不需要依賴具體的模塊代碼,即可快速搭建一個應用系統,而模塊內業務邏輯變化的時候,只要接口保持一致就不會影響業務程序和其他模塊。

1.Web Service與企業級分佈式服務

2.大型網站分佈式服務的需求和特點

對於大型網站,除了Web Services所提供的服務註冊與發現,服務調用等標準功能,還需要分佈式服務框架能夠支持如下功能。

1.負載均衡
2.失效轉移
3.高效的遠程通信
4.整合異構系統
5.對應用最少侵入
6.版本管理
7.實時監控

3.分佈式服務框架設計

例如Facebook的Thrift。

服務消費者程序通過服務接口使用服務,而服務接口通過代理加載具體服務,具體服務可以是本地的代碼模塊,也可以是遠程的服務,因此對應用較少侵入:應用程序只需要調用服務接口,服務框架根據配置自動調用本地或遠程實現。

服務框架客戶端模塊通過服務註冊中心加載服務提供者列表(服務提供者啓動後自動向服務註冊中心註冊自己可提供的服務接口列表),查找需要的服務接口,並根據配置的負載均衡策略將服務調用請求發送到某臺服務提供者服務器。如果服務調用失敗,客戶端模塊會自動從服務提供者列表選擇一個可提供同樣服務的另一臺服務器重新請求服務,實現服務的自動失效轉移,保證服務高可用。

7.4可擴展的數據結構

開放平臺是網站內部和外部交互的接口,外部需要面對衆多的第三方開發者,內部需要面對網站內諸多的業務服務。雖然每個網站的業務場景和需求都各不相同,但是開放平臺的架構設計卻大同小異,如圖所示。

API接口:是開放平臺暴露給開發者使用的一組API,其形式可以是RESTful、WebService、RPC等各種形式。
協議轉換:將各種API輸入轉換成內部服務可以識別的形式,並將內部服務的返回封裝成API的格式。
安全:除了一般應用需要的身份識別、權限控制等安全手段,開放平臺還需要分級的訪問帶寬限制,保證平臺資源被第三方應用公平合理使用,也保護網站內部服務不會被外部應用拖垮。
審計:記錄第三方應用的訪問情況,並進行監控、計費等。
路由:將開放平臺的各種訪問路由映射到具體的內部服務。
流程:將一組離散的服務組織成一個上下文相關的新服務,隱藏服務細節,提供統一接口供開發者調用。

7.6小結

既然我們知道網站不停上新產品是其生存的本能,誰能更快更好地推出更多的新產品,誰就活得更滋潤,那麼工程師就要做好準備應付這種局面。馬克思的勞動價值理論告訴我們,產品的內在價值在於勞動的時間,勞動的時間不在於個體付出的勞動時間,而在於行業一般勞動時間,資本家只會爲行業一般勞動時間買單,如果你的效率低於行業一般勞動時間,對不起,請你自願加班。反之,如果你有一個更具有擴展性的網站架構,可以更快速地開發新產品,也許你也享受不了只上半天班的福利,但是至少在這個全行業加班的互聯網領域,你能夠按時下班,陪陪家人,看看星星。

第三篇:案例

10.1Wikipedia網站整體架構

架構如圖。

Wikipedia架構的主要組成部分如下。
GeoDNS:基於開源域名服務器軟件BIND(Berkeley Internet Name Domain)的增強版本,可將域名解析到離用戶最近的服務器。
LVS:基於Linux的開源負載均衡服務器。
Squid:基於Linux的開源反向代理服務器。
Lighttpd:開源的應用服務器,較主流的Apache服務器更輕量、更快速。實踐中,有許多網站使用L ighttpd作爲圖片服務器。
PHP:免費的Web應用程序開發語言,最流行的網站建站語言。
Memcached:無中心高性能的開源分佈式緩存系統,穩定、可靠、歷久彌新,是網站分佈式緩存服務必備的。
Lucene:由Apache出品,Java開發的開源全文搜索引擎。
MySQL:開源的關係數據庫管理系統,雖被Oracle收購,但開源社區將其繼續開源發展的決心不動搖。

關於故障

在討論解決方案之前,我們先對故障進行分類,針對不同故障情況分別對待。對於一個分佈式存儲系統而言,影響系統整體可用性的故障可以分成以下三類。

× 瞬時故障:引起這類故障的主要原因是網絡通信瞬時中斷、服務器內存垃圾回收或後臺線程繁忙停止數據訪問操作響應。其特點是故障時間短,在秒級甚至毫秒級系統即可自行恢復正常響應。

× 臨時故障:引起這類故障的主要原因是交換機宕機、網卡鬆動等導致的網絡通信中斷;系統升級、停機維護等一般運維活動引起的服務關閉;內存損壞、CPU過熱等硬件原因導致的服務器宕機;這類故障的主要特點是需要人工干預(更換硬件、重啓機器等)才能恢復正常。通常持續時間需要幾十分鐘甚至幾小時。故障時間可分爲兩個階段:臨時故障期間,臨時故障恢復期間。

× 永久故障:引起這類故障的主要原因只有一個:硬盤損壞,數據丟失。雖然損壞硬盤和損壞內存一樣,可以通過更換硬盤來重新啓動機器,但是丟失的數據卻永遠找不回來了,因此其處理策略也和前面兩種故障完全不同,恢復系統到正常狀態也需要更長的時間。故障時間可分爲兩個階段:永久故障期間和永久故障恢復期間。

12.1秒殺活動的技術挑戰

1.對現有網站業務造成衝擊
2.高併發下的應用,數據庫負載
3.突然增加的網絡及服務器帶寬
4.直接下單

12.2秒殺系統的應對策略

1.秒殺系統獨立部署
2.秒殺商品頁面靜態化
3.租借秒殺活動網絡帶寬
4.動態生成隨機下單頁面URL

13.3高併發情況下鎖引發的故障

故障現象:某應用服務器不定時地因爲響應超時而報警,但是很快又超時解除,恢復正常,如此反覆,讓運維人員非常苦惱。

原因分析:程序中某個單例對象(singleton object)中多處使用了synchronized(this),由於this對象只有一個,所有的併發請求都要排隊獲得這唯一的一把鎖。一般情況下,都是一些簡單操作,獲得鎖,迅速完成操作,釋放鎖,不會引起線程排隊。但是某個需要遠程調用的操作也被加了synchronized(this),這個操作只是偶爾會被執行,但是每次執行都需要較長的時間才能完成,這段時間鎖被佔用,所有的用戶線程都要等待,響應超時,這個操作執行完後釋放鎖,其他線程迅速執行,超時解除。

經驗教訓:
× 使用鎖操作要謹慎。

第四篇:架構師

發佈了105 篇原創文章 · 獲贊 19 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章