高併發“葵花寶典”,看不懂算我輸!

冰凍三尺非一日之寒,系統設計也如此,好的架構是不斷演進的。一般來說能夠用單塊架構解決的問題,儘量不要採用分佈式。

分佈式雖然可以提高系統的響應能力,也帶來了更高的複雜性,如果團隊技術人員水平hold不住的話,反而會產生更多問題,例如問題難以定位,系統性能下降,某種業務實現困難或無法實現等問題。

以下內容由偉大的詩人chenqionghe整理,light weight baby~

常用指標

響應時間

直觀反應系統快慢,一般控制在200ms以內,超過1s用戶已經能感覺到慢了

併發數

同時處理請求的數目

QPS

每秒查詢請求數

TPS

每秒執行事務數,著重反應寫

奪命三高

高併發

通過設計讓系統能接收更多的用戶併發請求,承擔更大的流量。一般考查併發數、QPS和TPS。

高併發“葵花寶典”,看不懂算我輸!

示例:廬山百龍霸,併發百龍

高性能

一般指服務響應時間快

  • 用戶視角。APP、瀏覽器上直接感受快
  • 開發視角。響應延遲低,系統吞吐量大,併發處理能力強
  • 運維視角。基礎設施配置高,CPU多核心,內存大
高併發“葵花寶典”,看不懂算我輸!

示例:雅典娜之驚歎,三位黃金聖鬥士將自身的究極小宇宙集中在一點進行攻擊

高可用

系統通過設計,減少停工時間,保持服務的高度可用性。一般會用SLA協議衡量服務可用性,用幾個九來衡量以一年為例,1年 = 365天 = 8760小時

  • 99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小時
  • 99.99 = 8760 * 0.0001 = 0.876小時 = 0.876 * 60 = 52.6分鐘
  • 99.999 = 8760 * 0.00001 = 0.0876小時 = 0.0876 * 60 = 5.26分鐘
    SLA提供的可用性越高,那麼一年內停機的時間越小。高可用的一種量化指標
高併發“葵花寶典”,看不懂算我輸!

示例:雅典娜之驚歎,分成不同的小組放招

常見招式

分流

高併發“葵花寶典”,看不懂算我輸!

例如nginx、hproxy、traefik,本質就是將流量分攤到不同的節點,負載均衡舉例:星巴克開分店,增加營業員、擴大面積

緩存

高併發“葵花寶典”,看不懂算我輸!

例如:Redis緩存、Memcached舉例:提供超市熱賣攤位,提高顧客購買效率;早餐店先提前把早餐做好,顧客來直接取

隊列

高併發“葵花寶典”,看不懂算我輸!

  • 提高響應速度。
    未處理完成前提前返回,提高響應速度,處理完後再發通知。
  • 緩衝流量,削峰填谷
    為了避免大量的請求衝擊後端服務,可以使用消息隊列暫存請求,後端服務按照自己的處理能力,從隊列中消費,例如秒殺、埋點場景。
    簡單地說,就是業務上游隊列緩衝,限速發送;業務下游隊列緩衝,限速執行
    針對 秒條場景,一般兩種方式,加鎖。比如golang包中的mutex,也可以利用redis本身操作原子性的特點寫入消息隊列。在消息隊列中做減庫存的操作
  • 系統解耦
    例如一個下單的信息需要同步多個子系統,每個子系統都需要保存訂單的數據的一部分,如果靠訂單服務的團隊維護所有子系統同步,耦合太大,這時候可以通過發佈訂閱模型,訂單服務在訂單變化時發送一條消息到一個主題中,所有的下游子系統都訂閱主題,這樣可以每個子系統都可以獲得訂單數據。

舉例:去海盜蝦飯吃飯,先結賬,做好了給你端過來

CDN

高併發“葵花寶典”,看不懂算我輸!

CDN(Content Delivery Network)官方定義叫內容分發網絡。簡單的說就是一種緩存,原理是將靜態的資源分發到多個地埋位置機房的服務器上,最終可以達到就近獲取數據達到提速的效果,例如北京地區訪問北京的數據,海南訪問海南的。當然,這也不用我們自己開發,例如阿里雲、七牛雲等知名雲廠商都提供了CDN服務。一般使用就是設置CDN回源更新數據的地址,將服務域名解析到雲廠商返回的CNAME上。

舉例:京東購買東西,發貨都直接從最近的倉庫發貨,只有倉庫沒貨了才會到源頭取貨(回源)

池化

高併發“葵花寶典”,看不懂算我輸!

一般連接的創建是比較耗資源和時間,一般我們可以使用連接池來提升效率,這就是傳說中的池化技術,常見的有數據連接池、線程池。

設定空閒連接數和最大連接數,步驟一般如下:

  1. 當前連接數小於空閒連接數,創建
  2. 連接池中有空閒連接直接使用
  3. 沒有空閒連接,當前連接數小於最大連接數,創建
  4. 達到或超過最大連接數,按設定超時時間等待舊連接釋放,超時拋出錯誤

本質都是空間換時間,一般創建的連接對象會放到一個隊列中。

擴容

  • 垂直擴容升配置,例如加CPU核心、加內存、改為IO優化型存儲
  • 水平擴容直接加機器,多多益善

熔斷

高併發“葵花寶典”,看不懂算我輸!

當某服務調用的時候,如果返回錯誤或者超時次數超過一定閾值後,後續請求不再發送直接返回錯誤舉例:就像電路的熔斷器一樣,電流過載,自動斷開電路。開源方案有:hystrix、traefik、istio,

限流

高併發“葵花寶典”,看不懂算我輸!

通過限制到達系統的併發請求數量,保證系統能正常響應部分用戶的請求。超過限制的流量,通過拒絕服務的方式保證整體系統的可用性。

舉例:十一假期去莫高窟旅遊,景點只放出有限的門票,門票賣完,新來的客戶不再接待。可以在系統中埋下限流的代碼,例如可以使用golang的緩衝channel實現。

降級

就像被沙加剝奪了五感一樣

高併發“葵花寶典”,看不懂算我輸!

例如雙十一的時候,打開淘寶,會發現界面上的信息少了很多,其實這就是一種降級,關閉或者拒絕很多不重要的功能,節省服務器資源抵禦高併發大流量。

分層

高併發“葵花寶典”,看不懂算我輸!

好處:分工明確,方便複用、容易針對層做擴展。這個分層,可以指代碼架構,也可以指服務架構,一般不跨層調用

  • MVC控制器(C)調用模型(M)取數據,再通過(V)渲染視圖。業務邏輯一般寫到模型中進行復用,但是可能會帶來的是模型之間的職責劃分不明確。所以一般還會在其中加入Service層,使Model模型不再存放業務邏輯。
  • Web、Service、DaoWeb:表現層。可以簡單理解成Controller和ViewService:業務邏輯層。業務邏輯都封裝到這一層,這一層直接調用Dao取數據Dao:數據訪問層。負責訪問數據庫,最常見的是AR模型或者ORM可以簡單理解成MVC加了一層Service,Controller直接調用Service,Service再調用Model
  • Web、Service、Manager、Dao在Service和Dao之間加了一層Manager,抽取service層之間的共同邏輯。

部署分級

高併發“葵花寶典”,看不懂算我輸!

根據優先級的高級將服務部署到不同的物理機上,可以通過K8S的label選擇最終部署的節點

日誌監控

高併發“葵花寶典”,看不懂算我輸!

  • 日誌追蹤。
    使用ELK或者阿里雲日誌服務。請求和打日誌傳遞requestId,查詢根據requestId檢索請求相關的所有日誌
  • 調用鏈追蹤.

    開源方案Zipkin,Jaeger 。核心是通過TranceId和SpanId追蹤每次調用
  • Prometheus監控
    把需要監控的指標存儲到prometheus中,通過grafanan展示
  • Sentry監控
    統一搜集採集異常日誌,針對500這種錯誤到sentry後臺查詢,比較方便定位問題

讀寫分離

高併發“葵花寶典”,看不懂算我輸!

將讀請求和寫請求分推到不同的實例,例如MySQL讀寫分離、Redis讀寫分離MySQL主從分離核心是binlog,主庫將binlog寫入relay log文件,從庫過來拉取。

主從同步容易遇到延遲問題,例如主庫已經寫入了,從庫查詢的還是老數據,一般會通過以下方式解決:

  1. 直接讀主庫
  2. 更新主庫前寫緩存,讀緩存
  3. 直接將更新的數據傳遞,不查庫

分庫分表

高併發“葵花寶典”,看不懂算我輸!

一般會配合服務一起拆分

  • 垂直拆分。
    專門的服務使用專門的庫。例如一個購買流程,可以拆分為商品庫、訂單庫。
  • 水平拆分。
    例如將users拆成10個庫,users0、users1...users9,根據某個字段的取模存放到不同的庫。

缺點:

  • 無法做join
  • 統計數量也是個問題
  • 不能再使用事務

查詢優化

高併發“葵花寶典”,看不懂算我輸!

  • 優化sql索引。分析sql執行效率,通過加索引優化
  • 引入Elasticsearch。提高搜索效率,降低模糊搜索給數據庫帶來的壓力。

作者:雪山飛豬

來源:
https://www.cnblogs.com/chenqionghe/p/12736957.html


分享到:


相關文章: