網(wǎng)上有很多關(guān)于pos機98發(fā)卡方超時,攜程10個有效降低客戶端超時的方法的知識,也有很多人為大家解答關(guān)于pos機98發(fā)卡方超時的問題,今天pos機之家(m.afbey.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機98發(fā)卡方超時
一、背景在現(xiàn)今的信息時代,微服務(wù)技術(shù)已成為一種重要的解決方案,微服務(wù)技術(shù)可以使系統(tǒng)的規(guī)模和功能變的更加靈活,從而獲得更高的可擴展性和可用性。然而,微服務(wù)調(diào)用中出現(xiàn)的超時問題,卻也成為系統(tǒng)可用性的一大隱患。超時會導(dǎo)致客戶端的性能下降,甚至可能無法正常工作。本文針對超時問題,提出相關(guān)的優(yōu)化手段,降低微服務(wù)調(diào)用超時的風(fēng)險。
1.1 誤區(qū)
當(dāng)我們遇到超時或執(zhí)行慢的問題時,我們往往會認為是依賴方出現(xiàn)了問題。
例如:訪問 Redis、DB、 RPC 接口變慢、超時,第一時間找依賴方排查問題,對方反饋的結(jié)論是,我這邊(服務(wù)端)沒有問題,請檢查一下你那邊(客戶端)是否有問題。
實際上,性能下降是一個非常復(fù)雜的問題,它可能涉及多個方面,包括服務(wù)端和客戶端。例如:代碼質(zhì)量、硬件資源、網(wǎng)絡(luò)狀況等問題都會導(dǎo)致性能下降,從而引發(fā)響應(yīng)慢、超時等問題。因此,我們需要全面地分析問題,找出影響性能的各種因素。
1.2 分享的目的
本文將詳細介紹我們在生產(chǎn)環(huán)境中遇到的慢執(zhí)行和超時等問題,并提出相關(guān)的優(yōu)化手段,通過優(yōu)化長尾性能,降低變慢或超時的風(fēng)險,提升系統(tǒng)的穩(wěn)定性。
二、超時的分類常見的超時一般有兩類:
a. 連接超時(ConnectTimeout):指建立網(wǎng)絡(luò)連接所需要的時間超出了設(shè)定的等待時間。
b. Socket 超時(SocketTimeout):指在數(shù)據(jù)傳輸過程中,客戶端等待服務(wù)端響應(yīng)的時間超出了設(shè)定的等待時間。
如下圖,①就是連接超時關(guān)注的時間,②就是 Socket 超時關(guān)注的時間,本文講解的超時為 Socket 超時。
圖1 客戶端請求過程
三、超時問題分析與優(yōu)化3.1 設(shè)置合理的超時時間
根據(jù)實際情況設(shè)置合理的超時時間,避免因為超時時間設(shè)置不合理導(dǎo)致的接口超時。
1)分析
看下客戶端設(shè)置的超時時間是否合理。比如調(diào)用服務(wù)端 P99.9 是100ms ,客戶端設(shè)置的超時時間是 100ms ,就會有 0.1% 的請求會超時。
2)優(yōu)化方案
我們在設(shè)置超時時間需要綜合考慮網(wǎng)絡(luò)延遲、服務(wù)響應(yīng)時間、GC 等情況。
以門票活動查詢引擎為例:
核心接口:最小值( P99.9*3 ,用戶可接受的等待時間),核心會影響到訂單,在用戶可接受范圍內(nèi)盡可能出結(jié)果。非核心接口:最小值( P99.9*1.5,用戶可接受的等待時間),非核心不影響訂單,不展示也沒關(guān)系。3.2 限流
當(dāng)系統(tǒng)遇到突發(fā)流量時,通過限流的方式,控制流量的訪問速度,避免系統(tǒng)崩潰或超時。
1)分析
看下超時時間點的請求量是否有突增,比如有某些突然的活動,這個時候應(yīng)用沒有提前擴容,面對突增流量會導(dǎo)致應(yīng)用負載比較高,從而導(dǎo)致超時問題。
2)優(yōu)化方案
評估當(dāng)前應(yīng)用最大可承載的流量,配置限流,維度可以是單機+集群。
單機限流:在面對突增流量時避免單機崩潰。
集群限流:在有限的資源下提供最大化的服務(wù)能力,保證系統(tǒng)穩(wěn)定性,不會出現(xiàn)崩潰或故障。
3.3 提升緩存命中率
提升緩存命中率,可以提高接口的響應(yīng)速度,降低接口的響應(yīng)時間,從而減少超時的發(fā)生。
1)分析
分析調(diào)用鏈路,找到慢的地方對其進行優(yōu)化,提升服務(wù)端的響應(yīng)速度。
如下圖所示,很明顯可以看到服務(wù)端執(zhí)行時間超過了客戶端配置的超時時間 200ms 導(dǎo)致超時。
圖2 客戶端調(diào)用服務(wù)端超時鏈路
繼續(xù)分析服務(wù)端執(zhí)行鏈路,發(fā)現(xiàn)是因為緩存沒有命中導(dǎo)致的。
圖3 緩存未命中鏈路
2)優(yōu)化方案
對于高并發(fā)系統(tǒng)來說,常見的是使用緩存來提升性能。
如下圖是之前的緩存架構(gòu),這種緩存架構(gòu)有兩個風(fēng)險。
a. 緩存是固定過期的,會導(dǎo)致某個時間大量 key 失效直接擊穿到數(shù)據(jù)庫。
b. 主動刷新機制是刪除緩存,監(jiān)聽數(shù)據(jù)庫 binlog 消息刪除緩存,如果大批量刷數(shù)據(jù)會導(dǎo)致大量 key 失效。
圖4 固定過期+懶加載模式
針對上面的風(fēng)險我們優(yōu)化了緩存架構(gòu),固定過期改為主動續(xù)期緩存,主動監(jiān)聽消息刷新緩存的方案,如下圖所示。
圖5 緩存前后架構(gòu)對比
3)效果
緩存命中率提升到 98% 以上,接口性能(RT)提升 50% 以上。
圖6 處理性能提升50%
這個緩存優(yōu)化方案在我們團隊之前寫的一篇文章《1分鐘售票8萬張!門票搶票背后的技術(shù)思考》中有詳細的介紹,具體細節(jié)這個地方不再展開,有興趣的同學(xué)可以自行閱讀。
3.4 優(yōu)化線程池
減少不合理的線程,降低線程切換帶來的超時。
1)分析
a. HTTP 線程數(shù)
先看下服務(wù)端 HTTP 線程數(shù)是否有明顯增加,且流量沒有增長,要確認 HTTP 線程數(shù)增加不是因為流量增長導(dǎo)致的。如下面兩張圖,流量正常的情況下 HTTP 線程數(shù)增加,說明是服務(wù)端響應(yīng)變慢導(dǎo)致,可以確認超時是服務(wù)端原因。
圖7 服務(wù)流量平穩(wěn)
圖8 HTTP線程數(shù)突增
b. 總線程數(shù)
再看下總線程數(shù)是否有增加(排除 HTTP 線程數(shù)),如果有,說明有使用多線程導(dǎo)致線程數(shù)量增加。這個時候需要 Dump 下線程,看下哪些線程使用的比較多。
2)解決方案
a. 統(tǒng)一管理線程池:動態(tài)配置參數(shù)+監(jiān)控能力
通過工具類封裝統(tǒng)一的線程池,提供動態(tài)配置參數(shù)和線程池監(jiān)控能力。
效果線程池具備監(jiān)控能力,如下圖是最小值(核心線程數(shù))、最大值(最大線程數(shù))和當(dāng)前線程池中線程數(shù)量的監(jiān)控,可以參考這個來調(diào)整線程池參數(shù)。
圖9 線程池水位線監(jiān)控
b. 異步改同步:小于10ms 的不使用多線程
高并發(fā)的場景下線程太多,線程調(diào)度時間得不到保障,一次任務(wù)需要多個 CPU 時間片,下一次調(diào)度的時間無法得到保障。
如下圖是一個線程池執(zhí)行耗時埋點,通過埋點發(fā)現(xiàn) A 在線程池中執(zhí)行的比較快,平均線和 P95 都在 10ms 以下,沒有必要使用線程池,改成同步執(zhí)行。
圖10 優(yōu)化前執(zhí)行耗時
效果接口性能提升明顯,平均線從 2.7ms 降低到 1.6ms,P99.9 從 23.7ms 降低到 1.7ms。
之前使用多線程,請求量有波動的時候線程增加比較多,導(dǎo)致線程調(diào)度時間得不到保障,體現(xiàn)到 P99.9 就很高。
圖11 優(yōu)化前后耗時對比
另外可以明顯看到總線程數(shù)也相應(yīng)減少了很多。
圖12 異步改同步后總線程數(shù)減少
3.5 優(yōu)化 GC
優(yōu)化 GC,減少 GC 的停頓時間,提高接口的性能。
1 )分析
首先看超時時間點是否有 Full GC,沒有再看下 Yong GC 是否有明顯的毛刺,如下圖可以看到 3 個明顯的毛刺。
圖13 Yong GC時間
如果超時的時間點(如下圖)可以對應(yīng)上 GC 毛刺時間點,那可以確認問題是由于Yong GC 導(dǎo)致。
圖14 客戶端調(diào)用服務(wù)端超時次數(shù)
2)解決方案
a. 通用性 JVM 參數(shù)調(diào)優(yōu)
檢查 -Xmx -Xms 這兩個值設(shè)置的是否一樣,如果不一樣 JVM 在運行時會根據(jù)實際情況來動態(tài)調(diào)整堆大小,這個調(diào)整頻繁會有性能開銷,并且初始化堆較小的話,GC 次數(shù)會比較頻繁。
效果-Xmx3296m -Xms1977m 改成 -Xmx3296m -Xms3296m 后效果如下圖所示,頻率和時間都有明顯的下降。
圖15 通用性JVM參數(shù)調(diào)優(yōu)后效果
b. G1 垃圾回收器參數(shù)調(diào)優(yōu)
背景:如果沒有設(shè)置新生代最大值和最小值或者只設(shè)置了最大值和最小值中的一個,那么 G1 將根據(jù)參數(shù) G1MaxNewSizePercent(默認值為60)和 G1NewSizePercent(默認值為5)占整個堆空間的比例來計算最大值和最小值,會動態(tài)平衡來分配新生代空間。
JVM剛啟動默認分配新生代空間是總堆的 5%,隨著流量的增加,新生代很容易就滿了,從而發(fā)生 Yong GC,下一次重新分配更多新生代空間,直到從默認的 5% 動態(tài)擴容和合適的初始值。這種配置在發(fā)布接入流量或者大流量涌入時容易發(fā)生頻繁的 Yong GC。
針對這類問題,優(yōu)化方案是調(diào)大 G1NewSizePercent,調(diào)大初始值,讓 GC 更加平穩(wěn)。這個值需要根據(jù)業(yè)務(wù)場景參考GC日志中Eden初始大小分布來設(shè)置,太大可能會導(dǎo)致 Full GC 問題。
以查詢引擎為例,根據(jù) GC 日志分析,新生代大小占堆比例在 35% 后相對平穩(wěn),設(shè)置的參數(shù)為:-XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=35
效果優(yōu)化后效果如下圖,可以看到優(yōu)化之后 GC 次數(shù)從 27次/min 降低到 11次/min,GC 時間從 560ms 降低到 250ms。
圖16 G1參數(shù)調(diào)優(yōu)后效果
3.6 線程異步改成 NIO 異步編程
NIO(非阻塞 IO)可以減少線程數(shù)量,提高線程的利用率,從而降低線程切換帶來的超時。
1)分析:CPU 指標(biāo)
分析 CPU 相關(guān)指標(biāo),如果出現(xiàn) CPU 利用率正常,CPU Load 高需要重點關(guān)注(如果是CPU 利用率高的情況,說明 CPU 本身就很繁忙,那 CPU Load 高也比較正常)。
在分析之前,先介紹幾個概念:
a. CPU時間片
CPU 將時間分成若干個時間片,每個時間片分配給一個線程使用。當(dāng)一個時間片用完后,CPU 會停止當(dāng)前線程的執(zhí)行,進行上下文切換到下一個任務(wù),以此類推。
這樣可以讓多個任務(wù)在同一時間內(nèi)并發(fā)執(zhí)行,提高系統(tǒng)的效率和響應(yīng)速度。
下圖模擬了單核 CPU 執(zhí)行的過程,需要注意的進行上下文切換是需要開銷的,但實際一次上下文切換需要的時間很短(一般是微秒級別)。
圖17 CPU執(zhí)行線程流程
b. CPU利用率
按時間片維度來理解,假設(shè)每次時間片都正好被使用完。
c. CPU Load
從上面概念分析,如果出現(xiàn) CPU 利用率正常,但是 CPU Load 高,那說明 CPU 空閑時間片、等待線程數(shù)很多,正在使用的時間片很少,這種情況要減少 CPU Load 需要減少等待線程數(shù)。
2)分析:實際案例
我們之前生產(chǎn)遇到過多次 CPU Load 高 CPU 利用率正常的情況。問題出現(xiàn)前后代碼沒有變動,比較明顯的變化是流量有上漲。排查代碼發(fā)現(xiàn)有使用線程池并發(fā)調(diào)用接口的地方,調(diào)用方式如下圖。
圖18 線程池執(zhí)行模型
這種方式在流量較低的情況下看不出什么問題,流量變高會導(dǎo)致需要的線程數(shù)量成倍增加。
例如:一次請求 A 需要調(diào)用 BCD 3個接口,那100個并發(fā)需要的線程數(shù)就是100 + 3*100=400(第一個100是A對應(yīng)的主線程,后面的3*100是 BCD 需要的100個線程)。
3)解決方案
線程池并發(fā)調(diào)用改成 NIO 異步調(diào)用,如下圖所示。
和之前對比,100 個并發(fā),需要的線程數(shù)也是 100(這個地方不考慮 NIO 本身的線程,這個是全局的,并且是相對固定很少的線程數(shù))。
圖19 NIO異步調(diào)用執(zhí)行模型
4)效果
超時問題沒再出現(xiàn),CPU Load 平均下降50%,之前 Load 經(jīng)常超過2(CPU 核數(shù)為2),改造之后 Load 降到 0.5 左右。
圖20 CPU Load優(yōu)化后效果
3.7 啟動階段預(yù)熱
啟動階段預(yù)熱可以提前建立鏈接,減少流量接入時的鏈接建立,從而降低超時的發(fā)生。
1)分析
應(yīng)用拉入后出現(xiàn)大量超時,并且 CPU Load 高 CPU 利用率正常,說明有很多等待線程,這種是拉入后有大量請求在等待被處理。
之前我們生產(chǎn)遇到過是在等待 Redis 建立鏈接,建鏈的過程是同步的,應(yīng)用剛拉入請求量瞬間涌入就會導(dǎo)致大量請求在等待 Redis 建鏈完成。
2)解決方案
啟動階段預(yù)熱提前建立鏈接,或者是配置 Redis 的最小空閑連接數(shù)。其他資源準(zhǔn)備也可以通過啟動階段預(yù)熱完成,比如 DB 鏈接、本地緩存加載等。
3.8 優(yōu)化 JIT
JIT(Just-In-Time)編譯可以提高程序的運行效率,灰度接入流量將字節(jié)碼編譯成本地機器碼,避免對接口性能的影響。
1)JIT 介紹
JIT 是 Just-In-Time 的縮寫,意為即時編譯。JIT 是一種在程序運行時將字節(jié)碼編譯為本地機器碼的技術(shù),可以提高程序的執(zhí)行效率。
在 Java 中,程序首先被編譯為字節(jié)碼,然后由 JVM 解釋執(zhí)行。但是,解釋執(zhí)行的效率較低,因為每次執(zhí)行都需要解釋一遍字節(jié)碼。為了提高程序的執(zhí)行效率,JIT 技術(shù)被引入到 Java 中。JIT 會在程序運行時,將頻繁執(zhí)行的代碼塊編譯為本地機器碼,然后再執(zhí)行機器碼,這樣可以大大提高程序的執(zhí)行效率。
2)分析
JIT 技術(shù)可以根據(jù)程序的實際運行情況,動態(tài)地優(yōu)化代碼,使得程序的性能更好。但是JIT 編譯過程需要一定的時間,因此在程序剛開始運行時,可能會出現(xiàn)一些性能瓶頸。
如下圖應(yīng)用拉入后 JIT 時間很久,那可以確認是 JIT 導(dǎo)致超時。
圖21 JIT執(zhí)行時間
3)解決方案
優(yōu)化 JIT 一個比較好的方案是開啟服務(wù)預(yù)熱(預(yù)熱功能攜程 RPC 框架是支持的)。
原理是讓應(yīng)用拉入后不是立馬接入100% 流量,而是隨著時間移動來逐漸增加流量,最終接入100% 流量,這種會讓小部分流量將熱點代碼提前編譯好。
4)效果
開啟服務(wù)預(yù)熱后,如下圖所示,應(yīng)用流量是逐漸增加的,可以看到響應(yīng)時間隨著時間越來越低,這就達到了預(yù)熱的效果。
圖22 服務(wù)拉入后請求量和響應(yīng)時間
3.9 換宿主機
當(dāng)宿主機負載過高時,可以考慮更換宿主機,避免宿主機負載過高影響容器負載。
1)分析
a. CPU Throttled 指標(biāo)
看下應(yīng)用 CPU 節(jié)流指標(biāo),CPU 節(jié)流會導(dǎo)致 CPU 休眠引起服務(wù)停頓。如果 CPU 利用率正常還是出現(xiàn)了 CPU 節(jié)流,這種大多數(shù)都是宿主機問題導(dǎo)致。
圖23 CPU節(jié)流情況
b. 宿主機指標(biāo)
排查宿主機 CPU 利用率、CPU Load、磁盤、IO 等指標(biāo)是否正常,如下圖 CPU Load在某個時刻后大于1說明宿主機負載較大。
圖24 宿主機CPU Load監(jiān)控
2)解決方案
重啟機器換宿主機。
3.10 優(yōu)化網(wǎng)絡(luò)
排查不穩(wěn)定的網(wǎng)絡(luò)線路,保證網(wǎng)絡(luò)的穩(wěn)定性。
1)分析
網(wǎng)絡(luò)的重點看下 TCPLostRetransmit(丟失的重傳包)指標(biāo)。比如下圖,某個點指標(biāo)異常,而這個點其他指標(biāo)都正常,那可以初步懷疑是網(wǎng)絡(luò)問題導(dǎo)致,最終確認需要找網(wǎng)絡(luò)相關(guān)團隊確認。
圖25 TCPLostRetransmit指標(biāo)
2)解決方案
找網(wǎng)絡(luò)相關(guān)團隊排查優(yōu)化。
四、總結(jié)回顧全文,主要講解遇到超時問題怎么分析、怎么定位、怎么優(yōu)化,從簡單到復(fù)雜總結(jié)了 10 種常見的優(yōu)化方法。這些方法不一定能解決其他不同業(yè)務(wù)場景的超時問題,具體需要結(jié)合自己的實際業(yè)務(wù)場景來驗證。
本文總結(jié)的方法都是我們在生產(chǎn)中遇到的真實情況,通過不斷實踐總結(jié)出來的,希望這些內(nèi)容能夠給閱讀本文的同學(xué)帶來一定的收獲。
4.1 優(yōu)化注意事項
超時時間設(shè)置和 GC 調(diào)優(yōu)需要結(jié)合自己業(yè)務(wù)場景來優(yōu)化。NIO 異步編程改造成本、復(fù)雜度較高,我們也在探索更簡單的方式,例如 JDK19 引入的虛擬線程(類似 Go 協(xié)程),可以用同步編程方式來實現(xiàn)異步的效果?!咀髡吆喗椤?p>Wen,攜程資深后端開發(fā)工程師,專注系統(tǒng)性能、穩(wěn)定性、交易系統(tǒng)等領(lǐng)域。以上就是關(guān)于pos機98發(fā)卡方超時,攜程10個有效降低客戶端超時的方法的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機98發(fā)卡方超時的知識,希望能夠幫助到大家!
