對號入座,快看看你的應(yīng)用系統(tǒng)用了哪些高并發(fā)技術(shù)?
一 系統(tǒng)簡介
百舸流量運營平臺承接著京東金融APP核心資源位和京東APP部分重要資源位,大促單接口QPS達到10w+,壓測單接口到20w+,典型的c端讀鏈路高并發(fā)場景。接下來,聊聊我們的系統(tǒng)都有哪些應(yīng)對高并發(fā)的“武功秘籍”。
二 “武功秘籍”
1 緩存(redis緩存,本地緩存)
緩存是提高系統(tǒng)的并發(fā)和提升系統(tǒng)的性能利器。redis分布式緩存用來解決緩存容量和性能問題,本地緩存用來解決redis的熱key問題和提升性能。
詳情可以查看之前的文章《服務(wù)端應(yīng)用多級緩存架構(gòu)方案》。
2 限流
限流是保護系統(tǒng)的一種策略,限流是控制接受請求的速率,通過壓測提前預(yù)知系統(tǒng)可承載的并發(fā)量,是對系統(tǒng)資源的前置保護,保證系統(tǒng)容量范圍內(nèi)的請求能夠正常返回,超過容量的請求丟棄。
可通過JSF配置限流或者sentinel實現(xiàn)限流。經(jīng)典算法:令牌桶,漏桶,滑動時間窗口。
3 熔斷降級
熔斷也是保護系統(tǒng)的一種手段,分布式系統(tǒng)中系統(tǒng)之間通過微服務(wù)調(diào)用,偶爾會出現(xiàn)依賴的某個服務(wù)不可用或者耗時驟增,導(dǎo)致耗盡業(yè)務(wù)線程池,從而拖垮整個服務(wù),可通過sentinel配置慢調(diào)用比例或者異常比例策略,達到熔斷閾值后,接下來的熔斷時長內(nèi)請求會自動被熔斷。經(jīng)過熔斷時長后熔斷器會進入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個請求成功通過后,則結(jié)束熔斷,否則繼續(xù)熔斷。 實際過程中,需要結(jié)合上下游鏈路,設(shè)置合理的超時時間以及兜底數(shù)據(jù)。
常見的降級類型有:日常降級;大促非核心接口降級;大促日志降級,只打印error級別日志。
4 異步(CompletableFuture,MQ)
系統(tǒng)解耦:完成一項業(yè)務(wù)指令通常需要多個微服務(wù)協(xié)作,核心業(yè)務(wù)完成后,可通過消息的方式進行異步解耦,讓其他服務(wù)訂閱消息,完成各自的業(yè)務(wù)邏輯,適用于無需用戶等待感知的場景。
提升性能:在C端用戶等待的感知的場景,需要多個微服務(wù)協(xié)作,如果串行RPC調(diào)用,耗時是每個服務(wù)耗時之和,可通過CompletableFuture實現(xiàn)RPC異步調(diào)用,當(dāng)使用時匯總結(jié)果,提升系統(tǒng)的性能。
5 池化技術(shù)
池化技術(shù)思想: 池化思想的解決的核心思想是通過預(yù)先創(chuàng)建數(shù)據(jù)庫連接或者線程放入池中,以便在需要時可以重復(fù)使用,減少創(chuàng)建和銷毀的開銷,提高系統(tǒng)的性能和并發(fā)。
數(shù)據(jù)庫連接池:如果是部署多臺機器,注意多臺機器連接數(shù)是否超過數(shù)據(jù)庫最大連接數(shù),避免出現(xiàn)連接不上問題。
業(yè)務(wù)線程池:自定義線程池,根據(jù)業(yè)務(wù)采用合適的拒絕策略,注意線程隔離,避免某個接口異常拖垮整個應(yīng)用。
6 代碼優(yōu)化
減少調(diào)用鏈路,優(yōu)化代碼邏輯執(zhí)行順序,將阻斷校驗流程前置,優(yōu)化數(shù)據(jù)結(jié)構(gòu)和算法,優(yōu)化查詢邏輯,減少IO次數(shù)等。
7 JVM調(diào)優(yōu)
使用G1垃圾回收器,應(yīng)用系統(tǒng)根據(jù)自己的業(yè)務(wù)情況配置JVM參數(shù),常規(guī)4C8G通用配置可參考:
-Xms4096m -Xmx4096m -XX:MaxMetaspaceSize=256m -XX:MetaspaceSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=80
核心參數(shù):-Xms初始堆大小,-Xmx最大堆大小,MaxMetaspaceSize最大元空間大小,MetaspaceSize表示Metaspace首次使用不足時觸發(fā)Full GC(全面垃圾回收)的閾值,垃圾回收機制使用G1回收器,MaxGCPauseMillis在jvm垃圾回收過程中允許停頓的最大毫秒時間。
8 分治思想,橫向擴展,
應(yīng)用服務(wù)應(yīng)該設(shè)計為無狀態(tài)的,可通過增加應(yīng)用實例數(shù)量來應(yīng)對突發(fā)流量,將流量分到每臺機器上,同樣可以將應(yīng)用進行按照業(yè)務(wù)拆分,單獨部署,提高系統(tǒng)并發(fā)。
合并批量請求,將多次調(diào)用改為一次批量調(diào)用,減少網(wǎng)絡(luò)開銷。
9 預(yù)熱
通過定時任務(wù)或者初始化腳本提前將數(shù)據(jù)加載到內(nèi)存,提高系統(tǒng)的性能,常見的有緩存數(shù)據(jù)預(yù)熱,ES數(shù)據(jù)預(yù)熱等。
針對應(yīng)用升級或者重啟抖動,可以通過JSF預(yù)熱的方式,應(yīng)用重啟后,在預(yù)熱時間內(nèi),流量逐漸增加的方式,減少抖動。
JSF預(yù)熱可參考文章《后端服務(wù)之應(yīng)用預(yù)熱》
10 數(shù)據(jù)異構(gòu)
業(yè)務(wù)數(shù)據(jù)通常存儲在支持事務(wù)的關(guān)系型數(shù)據(jù)庫中,當(dāng)在面對復(fù)雜查詢場景時捉襟見肘,可將數(shù)據(jù)通過binlog異構(gòu)到ES中,ES支持復(fù)雜場景的查詢并且有較高的性能,輕松突破數(shù)據(jù)庫單表數(shù)據(jù)量大及多表關(guān)聯(lián)查詢瓶頸。
數(shù)據(jù)異構(gòu)可參考文章《記一次生產(chǎn)慢sql索引優(yōu)化及思考》 中的目錄五:長期優(yōu)化方案。
11 分庫分表,數(shù)據(jù)庫優(yōu)化
分庫和分表各抗什么?
分表:當(dāng)一個表中的數(shù)據(jù)量過大時,會導(dǎo)致查詢速度變慢、插入和更新操作效率下降等問題。通過分表,每個小表的數(shù)據(jù)量就相對較小,性能問題得以緩解。
分庫:當(dāng)一個數(shù)據(jù)庫實例無法承受大量數(shù)據(jù)的存儲和并發(fā)時,可通過分庫來分散系統(tǒng)壓力。
通常情況下,分庫和分表是結(jié)合使用的。
數(shù)據(jù)庫優(yōu)化中常見的是sql優(yōu)化,是否命中索引,提高服務(wù)器硬件配置。
三 總結(jié)
以上為百舸系統(tǒng)處理高并發(fā)問題的一些策略,高并發(fā)架構(gòu)是演進而來,避免過度設(shè)計,沒有一個技術(shù)能解決所有的問題,抓住關(guān)鍵矛盾,使用前一定要做好調(diào)研和評估,還有哪些?歡迎補充。