天天看點

關于大型網站系統架構你不得不懂的10個問題(轉載)

轉載

1. 你使用過哪些元件或者方法來提升網站性能,可用性以及并發量

  1. 提高硬體能力、增加系統伺服器。(當伺服器增加到某個程度的時候系統所能提供的并發通路量幾乎不變,是以不能根本解決問題)
  2. 使用緩存(本地緩存:本地可以使用JDK自帶的 Map、Guava Cache.分布式緩存:Redis、Memcache.本地緩存不适用于提高系統并發量,一般是用處用在程式中。比如Spring是如何實作單例的呢?大家如果看過源碼的話,應該知道,S把已經初始過的變量放在一個Map中,下次再要使用這個變量的時候,先判斷Map中有沒有,這也就是系統中常見的單例模式的實作。)
  3. 消息隊列 (解耦+削峰+異步)
  4. 采用分布式開發 (不同的服務部署在不同的機器節點上,并且一個服務也可以部署在多台機器上,然後利用 Nginx 負載均衡通路。這樣就解決了單點部署(All In)的缺點,大大提高的系統并發量)
  5. 資料庫分庫(讀寫分離)、分庫分表(水準分庫、垂直分表)
  6. 采用叢集 (多台機器提供相同的服務)
  7. CDN 加速 (将一些靜态資源比如圖檔、視訊等等緩存到離使用者最近的網絡節點)
  8. 浏覽器緩存
  9. 使用合适的連接配接池(資料庫連接配接池、線程池等等)
  10. 适當使用多線程進行開發。

2. 設計高可用系統的常用手段

  1. 降級: 服務降級是當伺服器壓力劇增的情況下,根據目前業務情況及流量對一些服務和頁面有政策的降級,以此釋放伺服器資源以保證核心任務的正常運作。降級往往會指定不同的級别,面臨不同的異常等級執行不同的處理。根據服務方式:可以拒接服務,可以延遲服務,也有時候可以随機服務。根據服務範圍:可以砍掉某個功能,也可以砍掉某些子產品。總之服務降級需要根據不同的業務需求采用不同的降級政策。主要的目的就是服務雖然有損但是總比沒有好;
  2. 限流: 防止惡意請求流量、惡意攻擊,或者防止流量超出系統峰值;
  3. 緩存: 避免大量請求直接落到資料庫,将資料庫擊垮;
  4. 逾時和重試機制: 避免請求堆積造成雪崩;
  5. 復原機制: 快速修複錯誤版本。

3. 現代網際網路應用系統通常具有哪些特點?

  1. 高并發,大流量;
  2. 高可用:系統7×24小時不間斷服務;
  3. 海量資料:需要存儲、管理海量資料,需要使用大量伺服器;
  4. 使用者分布廣泛,網絡情況複雜:許多大型網際網路都是為全球使用者提供服務的,使用者分布範圍廣,各地網絡情況千差萬别;
  5. 安全環境惡劣:由于網際網路的開放性,使得網際網路更容易受到攻擊,大型網站幾乎每天都會被黑客攻擊;
  6. 需求快速變更,釋出頻繁:和傳統軟體的版本釋出頻率不同,網際網路産品為快速适應市場,滿足使用者需求,其産品釋出頻率是極高的;
  7. 漸進式發展:與傳統軟體産品或企業應用系統一開始就規劃好全部的功能和非功能需求不同,幾乎所有的大型網際網路網站都是從一個小網站開始,漸進地發展起來。

4. 談談你對微服務領域的了解和認識

5. 談談你對 Dubbo 和 Spring Cloud 的認識(兩者關系)

6. 性能測試了解嗎?說說你知道的性能測試工具?

性能測試指通過自動化的測試工具模拟多種正常、峰值以及異常負載條件來對系統的各項性能名額進行測試。性能測試是總稱,通常細分為:

  1. 基準測試: 在給系統施加較低壓力時,檢視系統的運作狀況并記錄相關數做為基礎參考.
  2. **負載測試:**是指對系統不斷地增加壓力或增加一定壓力下的持續時間,直到系統的某項或多項性能名額達到安全臨界值,例如某種資源已經達到飽和狀态等 。此時繼續加壓,系統處理能力會下降。
  3. 壓力測試: 超過安全負載情況下,不斷施加壓力(增加并發請求),直到系統崩潰或無法處理任何請求,依此獲得系統最大壓力承受能力。
  4. 穩定性測試: 被測試系統在特定硬體、軟體、網絡環境下,加載一定業務壓力(模拟生産環境不同時間點、不均勻請求,呈波浪特性)運作一段較長時間,以此檢測系統是否穩定。

後端程式員或者測試平常比較常用的測試工具是 JMeter(官網:https://jmeter.apache.org/)。Apache JMeter 是一款基于Java的壓力測試工具(100%純Java應用程式),旨在加載測試功能行為和測量性能。它最初被設計用于 Web 應用測試但後來擴充到其他測試領域。

7. 對于一個單體應用系統,随着産品使用的使用者越來越多,網站的流量會增加,最終單台伺服器無法處理那麼大的流量怎麼辦?

這個時候就要考慮擴容了。《億級流量網站架構核心技術》這本書上面介紹到我們可以考慮下面幾步來解決這個問題:

  • 第一步,可以考慮簡單的擴容來解決問題。比如增加系統的伺服器,提高硬體能力等等。
  • 第二步,如果簡單擴容搞不定,就需要水準拆分和垂直拆分資料/應用來提升系統的伸縮性,即通過擴容提升系統負載能力。
  • 第三步,如果通過水準拆分/垂直拆分還是搞不定,那就需要根據現有系統特性,架構層面進行重構甚至是重新設計,即推倒重來。

對于系統設計,理想的情況下應支援線性擴容和彈性擴容,即在系統瓶頸時,隻需要增加機器就可以解決系統瓶頸,如降低延遲提升吞吐量,進而實作擴容需求。

如果你想擴容,則支援水準/垂直伸縮是前提。在進行拆分時,一定要清楚知道自己的目的是什麼,拆分後帶來的問題如何解決,拆分後如果沒有得到任何收益就不要為了 拆而拆,即不要過度拆分,要适合自己的業務。

8. 大表優化的常見手段

當MySQL單表記錄數過大時,資料庫的CRUD性能會明顯下降,一些常見的優化措施如下:

  1. 限定資料的範圍: 務必禁止不帶任何限制資料範圍條件的查詢語句。比如:我們當使用者在查詢訂單曆史的時候,我們可以控制在一個月的範圍内;
  2. 讀/寫分離: 經典的資料庫拆分方案,主庫負責寫,從庫負責讀;
  3. 垂直分區: 根據資料庫裡面資料表的相關性進行拆分。 例如,使用者表中既有使用者的登入資訊又有使用者的基本資訊,可以将使用者表拆分成兩個單獨的表,甚至放到單獨的庫做分庫。簡單來說垂直拆分是指資料表列的拆分,把一張列比較多的表拆分為多張表。 如下圖所示,這樣來說大家應該就更容易了解了。
關于大型網站系統架構你不得不懂的10個問題(轉載)

垂直拆分的優點: 可以使得行資料變小,在查詢時減少讀取的Block數,減少I/O次數。此外,垂直分區可以簡化表的結構,易于維護。垂直拆分的缺點: 主鍵會出現備援,需要管理備援列,并會引起Join操作,可以通過在應用層進行Join來解決。此外,垂直分區會讓事務變得更加複雜;

4.水準分區: 保持資料表結構不變,通過某種政策存儲資料分片。這樣每一片資料分散到不同的表或者庫中,達到了分布式的目的。 水準拆分可以支撐非常大的資料量。 水準拆分是指資料表行的拆分,表的行數超過200萬行時,就會變慢,這時可以把一張的表的資料拆成多張表來存放。舉個例子:我們可以将使用者資訊表拆分成多個使用者資訊表,這樣就可以避免單一表資料量過大對性能造成影響。

關于大型網站系統架構你不得不懂的10個問題(轉載)

大的資料量。需要注意的一點是:分表僅僅是解決了單一表資料過大的問題,但由于表的資料還是在同一台機器上,其實對于提升MySQL并發能力沒有什麼意義,是以 水準拆分最好分庫 。水準拆分能夠 支援非常大的資料量存儲,應用端改造也少,但 分片事務難以解決 ,跨界點Join性能較差,邏輯複雜。《Java工程師修煉之道》的作者推薦 盡量不要對資料進行分片,因為拆分會帶來邏輯、部署、運維的各種複雜度 ,一般的資料表在優化得當的情況下支撐千萬以下的資料量是沒有太大問題的。如果實在要分片,盡量選擇用戶端分片架構,這樣可以減少一次和中間件的網絡I/O。

下面補充一下資料庫分片的兩種常見方案:

  • 用戶端代理: 分片邏輯在應用端,封裝在jar包中,通過修改或者封裝JDBC層來實作。 當當網的 Sharding-JDBC 、阿裡的TDDL是兩種比較常用的實作。
  • 中間件代理: 在應用和資料中間加了一個代理層。分片邏輯統一維護在中間件服務中。 我們現在談的 Mycat 、360的Atlas、網易的DDB等等都是這種架構的實作。

9. 在系統中使用消息隊列能帶來什麼好處?

《大型網站技術架構》第四章和第七章均有提到消息隊列對應用性能及擴充性的提升。

1) 通過異步處理提高系統性能

關于大型網站系統架構你不得不懂的10個問題(轉載)

如上圖,在不使用消息隊列伺服器的時候,使用者的請求資料直接寫入資料庫,在高并發的情況下資料庫壓力劇增,使得響應速度變慢。但是在使用消息隊列之後,使用者的請求資料發送給消息隊列之後立即 傳回,再由消息隊列的消費者程序從消息隊列中擷取資料,異步寫入資料庫。由于消息隊列伺服器處理速度快于資料庫(消息隊列也比資料庫有更好的伸縮性),是以響應速度得到大幅改善。

通過以上分析我們可以得出消息隊列具有很好的削峰作用的功能——即通過異步處理,将短時間高并發産生的事務消息存儲在消息隊列中,進而削平高峰期的并發事務。 舉例:在電子商務一些秒殺、促銷活動中,合理使用消息隊列可以有效抵禦促銷活動剛開始大量訂單湧入對系統的沖擊。如下圖所示: 

關于大型網站系統架構你不得不懂的10個問題(轉載)

資料寫入消息隊列之後就立即傳回給使用者了,但是請求資料在後續的業務校驗、寫資料庫等操作中可能失敗。是以使用消息隊列進行異步處理之後,需要适當修改業務流程進行配合,比如使用者在送出訂單之後,訂單資料寫入消息隊列,不能立即傳回使用者訂單送出成功,需要在消息隊列的訂單消費者程序真正處理完該訂單之後,甚至出庫後,再通過電子郵件或短信通知使用者訂單成功,以免交易糾紛。這就類似我們平時手機訂火車票和電影票。

2) 降低系統耦合性

我們知道子產品分布式部署以後聚合方式通常有兩種:1.分布式消息隊列和2.分布式服務。

先來簡單說一下分布式服務:

目前使用比較多的用來建構SOA(Service Oriented Architecture面向服務體系結構)的分布式服務架構是阿裡巴巴開源的Dubbo.如果想深入了解Dubbo的可以看我寫的關于Dubbo的這一篇文章:《高性能優秀的服務架構-dubbo介紹》:https://juejin.im/post/5acadeb1f265da2375072f9c

再來談我們的分布式消息隊列:

我們知道如果子產品之間不存在直接調用,那麼新增子產品或者修改子產品就對其他子產品影響較小,這樣系統的可擴充性無疑更好一些。

我們最常見的事件驅動架構類似生産者消費者模式,在大型網站中通常用利用消息隊列實作事件驅動結構。如下圖所示:

關于大型網站系統架構你不得不懂的10個問題(轉載)

消息隊列使利用釋出-訂閱模式工作,消息發送者(生産者)釋出消息,一個或多個消息接受者(消費者)訂閱消息。 從上圖可以看到消息發送者(生産者)和消息接受者(消費者)之間沒有直接耦合,消息發送者将消息發送至分布式消息隊列即結束對消息的處理,消息接受者從分布式消息隊列擷取該消息後進行後續處理,并不需要知道該消息從何而來。對新增業務,隻要對該類消息感興趣,即可訂閱該消息,對原有系統和業務沒有任何影響,進而實作網站業務的可擴充性設計。

消息接受者對消息進行過濾、處理、包裝後,構造成一個新的消息類型,将消息繼續發送出去,等待其他消息接受者訂閱該消息。是以基于事件(消息對象)驅動的業務架構可以是一系列流程。

另外為了避免消息隊列伺服器當機造成消息丢失,會将成功發送到消息隊列的消息存儲在消息生産者伺服器上,等消息真正被消費者伺服器處理後才删除消息。在消息隊列伺服器當機後,生産者伺服器會選擇分布式消息隊列伺服器叢集中的其他伺服器釋出消息。

備注: 不要認為消息隊列隻能利用釋出-訂閱模式工作,隻不過在解耦這個特定業務環境下是使用釋出-訂閱模式的,比如在我們的ActiveMQ消息隊列中還有點對點工作模式,具體的會在後面的文章給大家詳細介紹,這一篇文章主要還是讓大家對消息隊列有一個更透徹的了解。

10. 說說自己對 CAP 定理,BASE 理論的了解

CAP 定理

關于大型網站系統架構你不得不懂的10個問題(轉載)

在理論計算機科學中,CAP定理(CAP theorem),又被稱作布魯爾定理(Brewer's theorem),它指出對于一個分布式計算系統來說,不可能同時滿足以下三點:

  • 一緻性(Consistence) :所有節點通路同一份最新的資料副本
  • 可用性(Availability):每次請求都能擷取到非錯的響應——但是不保證擷取的資料為最新資料
  • 分區容錯性(Partition tolerance) : 分布式系統在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一緻性和可用性的服務。

CAP僅适用于原子讀寫的NOSQL場景中,并不适合資料庫系統。現在的分布式系統具有更多特性比如擴充性、可用性等等,在進行系統設計和開發時,我們不應該僅僅局限在CAP問題上。

注意:不是所謂的3選2(不要被網上大多數文章誤導了):

大部分人解釋這一定律時,常常簡單的表述為:“一緻性、可用性、分區容忍性三者你隻能同時達到其中兩個,不可能同時達到”。實際上這是一個非常具有誤導性質的說法,而且在CAP理論誕生12年之後,CAP之父也在2012年重寫了之前的論文。

當發生網絡分區的時候,如果我們要繼續服務,那麼強一緻性和可用性隻能2選1。也就是說當網絡分區之後P是前提,決定了P之後才有C和A的選擇。也就是說分區容錯性(Partition tolerance)我們是必須要實作的。

我在網上找了很多文章想看一下有沒有文章提到這個不是所謂的3選2,用百度半天沒找到了一篇,用谷歌搜尋找到一篇比較不錯的,如果想深入學習一下CAP就看這篇文章把,我這裡就不多BB了:《分布式系統之CAP理論》 :http://www.cnblogs.com/hxsyl/p/4381980.html

BASE 理論

BASE 是 Basically Available(基本可用) 、Soft-state(軟狀态) 和 Eventually Consistent(最終一緻性) 三個短語的縮寫。BASE理論是對CAP中一緻性和可用性權衡的結果,其來源于對大規模網際網路系統分布式實踐的總結,是基于CAP定理逐漸演化而來的,它大大降低了我們對系統的要求。

BASE理論的核心思想: 即使無法做到強一緻性,但每個應用都可以根據自身業務特點,采用适當的方式來使系統達到最終一緻性。也就是犧牲資料的一緻性來滿足系統的高可用性,系統中一部分資料不可用或者不一緻時,仍需要保持系統整體“主要可用”。

BASE理論三要素:

  1. 基本可用: 基本可用是指分布式系統在出現不可預知故障的時候,允許損失部分可用性。但是,這絕不等價于系統不可用。 比如: ①響應時間上的損失:正常情況下,一個線上搜尋引擎需要在0.5秒之内傳回給使用者相應的查詢結果,但由于出現故障,查詢結果的響應時間增加了1~2秒;②系統功能上的損失:正常情況下,在一個電子商務網站上進行購物的時候,消費者幾乎能夠順利完成每一筆訂單,但是在一些節日大促購物高峰的時候,由于消費者的購物行為激增,為了保護購物系統的穩定性,部分消費者可能會被引導到一個降級頁面;
  2. 軟狀态: 軟狀态指允許系統中的資料存在中間狀态,并認為該中間狀态的存在不會影響系統的整體可用性,即允許系統在不同節點的資料副本之間進行資料同步的過程存在延時;
  3. 最終一緻性: 最終一緻性強調的是系統中所有的資料副本,在經過一段時間的同步後,最終能夠達到一個一緻的狀态。是以,最終一緻性的本質是需要系統保證最終資料能夠達到一緻,而不需要實時保證系統資料的強一緻性。

8 張圖讀懂大型網站技術架構

參考

  • 《大型網站技術架構》
  • 《億級流量網站架構核心技術》
  • 《Java工程師修煉之道》
  • https://www.cnblogs.com/puresoul/p/5456855.html

繼續閱讀