分佈式架構 高併發處理
高併發介紹
- 在同時或者極短時間內,有大量請求到達服務端,每個請求都需要服務端耗費資源進行處理,並做出相應反饋
- 服務端比如同時開啓進程數,能同時運行的線程數、網絡連接數、CPU運算、I/O、內存都是有限,
所以服務端能同時處理請求也是有限的。高併發本質就是資源的有限性
如:1.系統在線人數10W,並不意味系統併發用戶是10W,可能存在10w用戶同時在首頁查看靜態文章,並未對服務器進行發送請求
那麼高併發數 是根據系統真實用戶數併發送請求需要服務端耗費資源進行處理的請求
2.服務端只能開啓100個線程,恰好1個線程處理一個請求需要耗時1s,那麼服務端1s只能處理100個請求,多餘請求無法處理
經典案例
- 商品、活動秒殺下訂單
準備階段
- 系統獨立部署
- 做好系統容量規劃(7-7.5折計算),系統優化、系統容災限流等方案
- 做好系統拆分,如:功能模塊、實時/非實時、動態/靜態等
- 參加活動商品設置定時上架時間
- 服務器時間同步(集羣中每臺機器時鐘要保持一致)
- 動態生成下單頁面的URL
實現階段
客戶端層面:
- 前端頁面採用h5靜態化,ajax獲取動態內容;如實時庫存、活動狀態、當前時間等
- 做CDN部署加速
- 靜態頁面和資源緩存 如:(圖片)
- JS針對請求過濾,減少請求發送到達服務端 如:(獲取驗證碼、時間截止或已售空自動結束等)
Web端層面:
- F5/LVS+Nginx接收高併發請求、並做負載均衡
- Lua腳本+Redis做請求隊列,針對有效請求用List排隊,並實現一些基本操作(限流、賬號參加次數檢查、同一IP請求數檢查)
Redis單線程高性能,每秒處理100W請求,如果大於100W請求如何處理呢?
1.可以結合Lua腳本控制請求數量並限流,有效減少redis壓力;比如100W請求,過濾20W,還剩80W,無效請求直接返回客戶端不到達服務端
2.如果應用非常龐大,用戶流量高額,Redis單節點做成集羣模式,請求處理數量也隨之增加 - Varnish緩存靜態頁面和靜態資源
- Tomcat集羣,預處理,通過業務場景判斷用戶是具備參加活動資格、賬號是否正常、是否在黑名單等
邏輯層面:
- 按照Redis請求隊列進行先後處理
- 純內存操作+異步(通過Redis完成減庫存,1.利用Redis的watch事物 2.利用Redis腳本Lua原子操作減庫存)
高併發產生問題,分析思考
- 服務端處理響應會逐漸變慢,甚至會丟失部分請求不處理,嚴重會導致服務器崩潰
- 客戶端(app\h5)、前端請求(nginx/varnish)、web服務器(webServer)、web應用(rmi/dubbo/遠程調用)、緩存(redis/membercache)、消息隊列(mq)、數據庫(db)都會面臨高併發等問題
高併發優化思路
客戶端層面
- 儘量減少請求數量,充分利用客戶端、瀏覽器自身緩存,如微服務前後端交互、網絡傳輸詳細記載,本文不在詳敘
- 儘量減少對服務端資源不必要浪費,如重複請求連接後端打開/關閉操作連接池
Nginx層面
- 動靜分離,靜態資源直接返回
- 負載均衡,如F5/LVS分流多個Nginx
- 根據系統業務,單獨拆分訪問(路徑)
Varnish層面
- 動態內容緩存、減少訪問後端服務
- 使用頁面片段緩存技術,如ESI
Web服務器層面
- 針對JVM配置進行合理優化
- 服務器配置進行優化,如:調整內存數量、線程數量等
- 相同服務部署多臺機器,實現負載均衡
- 增加資源,如增加網絡帶寬、高性能服務器、高性能數據庫 (立杆見效,服務器普通硬盤換SSD,數據庫換物理機等)
- 請求分流
1.使用集羣:如之前1臺處理100個請求,增加兩臺後,3臺機器虛擬組成一個集羣后,對外處理請求可以提升到300*80%=240
2.採用微服務架構,後續微服務架構高可用會詳細描述
Web應用層面(優化應用程序)
- 提高單個請求的處理速度,如上如果處理一個請求消耗從1s降低到0.5秒,併發就是200
- 耗時業務同步根據業務情況 使用mq異步處理
- 比如導入、導出耗時耗力 合理使用多線程批量處理、指向單臺應用獨立處理
- 高效使用緩存,減少鎖的使用範圍
- 優化訪問數據庫SQL
- 儘量避免遠程調用、大量I/O等耗時操作
- 合理規劃事物等比較耗資源操作
- 部分業務考慮採用預計算處理,減少實時計算耗資源操作 如:報表
- 不要盲目使用RPC、netty、http遠程網絡調用,如需特定調用注意加上超時時間
數據庫層面
- 合理使用數據庫引擎 如 mysql的InnoDB和MyISAM引擎
- 數據庫系統參數配置優化
- 特殊複雜計算耗時操作可以考慮使用存儲過程來處理
- 數據庫集羣,進行讀寫分離
- 合理設計數據庫表結構、索引 如(組合索引)
- 分庫、分區、分表降到單庫單表併發量
- 合理使用Nosql,如傳統、分佈式數據庫共存,根據數據特性合理存放(hbase、hive、mongoDB)
總結:
高併發並不只是單一渠道等問題,本文主要講述高併發涉及場景等具體詳細優化思路。
優化原則 分析定位哪個環節鏈路是高併發瓶頸,進行優化分而治之,最終提高請求處理速度。
筆者建議優化順序如下
1.web應用層面 核心優化web應用層面,80%高併發等問題都和低效應用程序有關係。
2.web服務器層面
3.客戶端層面
4.nginx層面
5.varnish層面
6.數據庫層面
作者簡介:張程 技術研究
更多文章請關注微信公衆號:zachary分解獅 (frankly0423)