有趣時刻
我的第一家公司就是電商公司,後面工作基本都是高併發服務開發,下面說下自己對於高併發的拙見。
先來認識下併發的關鍵術語:
併發量:就是說指定時間段內的訪問量,一般用TPS(每秒事務數),QPS(每秒查詢數),響應時間等指標進行表示!
何為高併發?短時間內有大量的請求訪問服務器,即TPS或者QPS很高!
高併發對服務器有著極高的要求,而這些要求主要集中在應用服務器和數據庫服務器上,所以一般高併發的解決通常是提高應用服務器和數據庫的處理能力!
針對應用服務器:
限流:比如說以前玩dota的時候,遇到遊戲平臺限流,登錄了也玩不了!一般限流通過某種算法(計數器,漏桶等)選擇性的讓一部分請求到達後臺,進行處理!
消峰:通常在電商的秒殺系統,活動等場景下,通常會在短時間內出現大量的流量,從正態分佈圖來看就是一個尖峰,如何讓訪問變得平緩呢?通常將請求放請求隊列,讓應用服務主動拉取,進行請求執行!
提高應用服務器能力:
①,連接能力:拋棄傳統的多線程(多進程)處理連接的方式,使用基於netty的IO多路複用的架構搭建服務器,提高連接能力,可使用nginx搭建應用服務集群實現負載均衡的同時,保證更多連接。
②,異步處理:避免同步處理引起的阻塞,使用異步調用能提升CPU使用率,避免資源浪費。
③,前後端分離:將前後端的代碼進行分離,避免彼此之間的影響,前端使用node.js,後端使用微服務架構,提升整體架構的處理能力。
④,集群或者微服務:使用nginx加幾臺應用服務器組成集群,或者業務解耦搭建微服務架構,避免單點宕機的危害!
⑤,緩存:使用redis,memcache等分佈式緩存,存儲臨時數據,定義表數據,配置等任何可以緩存的東西,藉助內存型緩存的快速特性得到更快的處理能力。
⑥,服務間通信:
接口調用:比如springcloud加eureka實現的服務,在eureka服務端實現服務列表的維護,接口的註冊和暴露,然後各個服務根據獲取的服務列表進行服務調用,可以使用feign實現客戶端的負載均衡,保證服務均衡調用。
消息中間件:使用kafka,ons,redis等消息中間件實現服務之間的消息傳遞,實現異步處理的同時,保證數據不丟失!
⑦,代碼優化:避免循環創建對象,線程等,減少使用加鎖操作,避免死鎖等可能出現的bug,減少對數據庫的頻繁訪問。
針對數據庫:
1,提升單個數據庫服務的能力,優化數據庫服務器性能,連接池優化,經常查看數據庫狀態(show status;)
2,集群:搭建主從複製,讀寫分離,雙主互備,分庫分表根據業務量選擇不同的集群方式,提供更加優異的性能。
3,利用數據庫中間件:使用canal實現數據同步到專門的查詢庫,或者緩存,使用mycat等組件實現分庫分表!
分佈式服務系統通常的瓶頸都在數據庫上,所以數據庫的搭建尤為重要。
同時,在高併發的系統中,還需要注意保持接口的冪等性,數據一致性(通常使用分佈式事務,參見我別的回答)!高併發系統瓶頸問題往往在測試過程中很難覆蓋,而在生產過程中爆發,所以是作為系統設計的一個難點通常是面試的必問點,上面涉及到的技術,由於篇幅原因,只是涉及到理論實現,實際更多的技術分享,敬請關注。。。
此生唯一
1,HTML靜態化 ,將活動頁面上的所有可以靜態的元素全部靜態化,並儘量減少動態元素。通過CDN來抗峰值。
4.如果請求過多,判定web服務器的壓力過大,增加前端的web服務器,做負載均衡
5.圖片服務器分離