歡迎來到「我是真的狗雜談世界」偶摔,關(guān)注不迷路
背景
最近一個(gè)項(xiàng)目上線前QA對壓測結(jié)果不是很滿意(并且表示之前的項(xiàng)目壓測結(jié)果也都不理想),于是我在上線后(上線前是肯定來不及了)開始了一輪性能測試够挂、排查和優(yōu)化藕夫,記錄一下整個(gè)過程。
思考過程
基礎(chǔ)信息
QA同學(xué)提供的壓測環(huán)境與結(jié)論:
- 施壓側(cè):
- 并發(fā)度100~300汁胆;
- 持續(xù)運(yùn)行120~300秒霜幼;
- 被壓側(cè):
- 單副本資源1C2G嫩码;
- 副本數(shù)1~4;
- 結(jié)果表現(xiàn):
- CPU:單副本100%(但有時(shí)出現(xiàn)某副本100%丢间,其他副本60~80%左右)烘挫;
- 內(nèi)存:單副本15~20%(但有時(shí)出現(xiàn)某副本高至50%)
- QPS:單副本100~120;
- 響應(yīng)耗時(shí):Avg(487~596ms)苛蒲;50TH(19~27ms)卤橄;90TH(1867~3099ms);95TH(2409~3902ms)臂外;99TH(4460~7002ms)窟扑;MAX(8589~13298ms)喇颁;
核心問題
關(guān)于性能、壓測等相關(guān)概念可參考「Foundation 11.性能是什么」
- QPS表現(xiàn)較低嚎货;
- CPU占用過高橘霎,很快被打滿;
- 響應(yīng)耗時(shí)存在少量(90TH以上)過高厂抖;
當(dāng)前這三者是有關(guān)聯(lián)的茎毁,當(dāng)前看來單個(gè)請求對于CPU資源需求較高,導(dǎo)致在小并發(fā)下CPU資源已占滿忱辅;
隨著并發(fā)度增高七蜘,系統(tǒng)通過頻繁調(diào)度來分配CPU資源,調(diào)度磨損增加(用于處理業(yè)務(wù)邏輯的比例降低)墙懂;
因此CPU占用過高也會一定程度拖累響應(yīng)耗時(shí)橡卤、QPS表現(xiàn)。
懷疑方向
- 硬件性能:之前有發(fā)現(xiàn)壓測環(huán)境結(jié)果較比生產(chǎn)環(huán)境低损搬,且兩側(cè)環(huán)境為獨(dú)立的集群碧库,因此懷疑兩側(cè)集群節(jié)點(diǎn)本身硬件性能差異較大;
- 執(zhí)行過程:由于是PHP FPM模式下運(yùn)行的服務(wù)巧勤,F(xiàn)astCGI處理過程嵌灰、PHP代碼解釋執(zhí)行過程等都可能造成CPU資源的占用、耗時(shí)颅悉;
- IO阻塞度:業(yè)務(wù)邏輯中復(fù)雜(多次)同步阻塞請求(三方HTTP接口沽瞭、MySQL、Redis)較比簡單(少次)會造成請求響應(yīng)需要時(shí)間變長剩瓶,降低QPS驹溃;
- 短連資源:整個(gè)服務(wù)對三方HTTP接口、MySQL延曙、Redis都采用的短連豌鹤,連接僅在請求周期內(nèi)復(fù)用,請求結(jié)束后釋放枝缔,對于連接的頻繁創(chuàng)建銷毀也會占用CPU資源布疙、耗時(shí);
- 框架磨損:新版開發(fā)框架投入使用后沒有太關(guān)注性能磨損問題愿卸,理論上這塊一定會存在磨損拐辽,只是程度和關(guān)鍵磨損點(diǎn)問題。
排查方法
(盡量)控制其他變量保持相同的情況下擦酌,針對要排查的環(huán)節(jié)俱诸、對象進(jìn)行多組壓測對比,記錄并分析得出結(jié)論赊舶。
實(shí)踐與結(jié)論
定位基準(zhǔn)
由于QA提供的結(jié)論看起來存在很多不穩(wěn)定性睁搭,因此我決定在壓測環(huán)境上基于該項(xiàng)目先進(jìn)行一波測試赶诊,作為后續(xù)對比、分析园骆、研究等排查工作的基準(zhǔn)舔痪。
第一波測試
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
2C2G | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 2 | 980 | - | - | - | - | - | - | 80 |
2C2G | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 2 | 490 | - | - | - | - | - | - | 90 |
從第一波測試記錄數(shù)據(jù)(因?yàn)镼PS表現(xiàn)已發(fā)生過于不穩(wěn)定現(xiàn)象了,其他數(shù)據(jù)就暫時(shí)沒有關(guān)注和記錄)很容易發(fā)現(xiàn)锌唾,除了我控制住的變量外锄码,一定還存在一個(gè)我沒發(fā)現(xiàn)的變量影響了壓測表現(xiàn);
而這兩次測試存在的變量只有兩個(gè):
- 測試時(shí)間:由于壓測服務(wù)做了串行控制(同一個(gè)時(shí)間點(diǎn)只能最多一個(gè)壓測任務(wù)執(zhí)行)晌涕,上述兩波測試是在不同的時(shí)間點(diǎn)進(jìn)行的滋捶。
- 被測副本:由于壓測環(huán)境需要很多配置成本,沒有分別配置兩套壓測環(huán)境余黎,上述兩波測試之間進(jìn)行了應(yīng)用副本重建(重新構(gòu)建了服務(wù))重窟。
為了進(jìn)一步排查上述兩個(gè)變量,我每次多次重建副本惧财,每次重建副本后進(jìn)行相隔一段時(shí)間的多組壓測巡扇,現(xiàn)象如下:
- 相同副本(不重建副本)中的表現(xiàn)是穩(wěn)定的(如果是500上下則一直是500上下,如果是1000上下則一直是1000上下)垮衷,甚至到第二天仍舊是穩(wěn)定的厅翔;
- 不同副本(重建副本)時(shí)的表現(xiàn)會發(fā)生波動(比如500變成1000,1000變500)搀突,但也不是每次重建都必然發(fā)生波動切換知给。
基于上述現(xiàn)象,基本可以排除時(shí)間差異描姚,而懷疑副本調(diào)度到的節(jié)點(diǎn)的硬件或其他基礎(chǔ)設(shè)施的差異導(dǎo)致;
我將此問題報(bào)告給服務(wù)器基礎(chǔ)設(shè)施團(tuán)隊(duì)后協(xié)助排查定位戈次,最終發(fā)現(xiàn)壓測環(huán)境4個(gè)節(jié)點(diǎn)其中1個(gè)節(jié)點(diǎn)的CPU基頻在1.5~3.5GHz之間動態(tài)波動(正常4個(gè)節(jié)點(diǎn)都應(yīng)該是3.5GHz)轩勘;
在他們解決問題的同時(shí),我管他們要了一個(gè)獨(dú)立節(jié)點(diǎn)來繼續(xù)我的測試份蝴,后面所有資源將按照下述描述:
- 新節(jié)點(diǎn):代表管他們要來的獨(dú)立節(jié)點(diǎn)单鹿,性能本身很差哥纫,2C表現(xiàn)還不如原節(jié)點(diǎn)1C好;
- 原節(jié)點(diǎn):代表除CPU異常節(jié)點(diǎn)之外的壓測環(huán)境節(jié)點(diǎn)(理論上與生產(chǎn)環(huán)境節(jié)點(diǎn)性能仍有差距)澄步;
- X號副本:代表副本重建,相同的X代表副本未經(jīng)過重建和泌;原節(jié)點(diǎn)有意義(由于壓測環(huán)境節(jié)點(diǎn)仍舊會有一些細(xì)微差異)村缸,新節(jié)點(diǎn)無意義(就只有一個(gè)節(jié)點(diǎn));
- 健康檢查:代表業(yè)務(wù)上一個(gè)接口直接返回武氓,沒有業(yè)務(wù)邏輯和三方請求梯皿;
- 簡單邏輯:代表業(yè)務(wù)上一個(gè)接口包含一個(gè)MySQL查詢仇箱;
- 簡單邏輯*x:代表業(yè)務(wù)上一個(gè)接口包含x個(gè)相同的MySQL查詢;
- 復(fù)雜邏輯:代表該項(xiàng)目業(yè)務(wù)真實(shí)邏輯(一個(gè)接口包含2~8次MySQL东羹、Redis剂桥、HTTP接口請求等);
繼續(xù)測試
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
2C2G属提;新節(jié)點(diǎn)权逗;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 1 | 162 | 5.63 | 6 | 6 | 6 | 8 | 20 | 31 |
1C2G;原節(jié)點(diǎn)冤议;1號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 1 | 496 | 1.63 | 2 | 2 | 2 | 2 | 217 | 80 |
1C2G斟薇;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 1 | 484 | 1.67 | 2 | 2 | 2 | 3 | 138 | 73 |
2C2G求类;新節(jié)點(diǎn)奔垦;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 5 | 526 | 8.66 | 6 | 7 | 40 | 47 | 1686 | 100 |
1C2G;原節(jié)點(diǎn)尸疆;1號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 5 | 660 | 6.43 | 2 | 2 | 72 | 77 | 2300 | 100 |
1C2G椿猎;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 5 | 624 | 6.9 | 2 | 3 | 73 | 78 | 900 | 100 |
2C2G寿弱;新節(jié)點(diǎn)犯眠;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 20 | 462 | 41.74 | 7 | 93 | 93 | 95 | 1858 | 100 |
1C2G;原節(jié)點(diǎn)症革;1號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 20 | 530 | 36.32 | 3 | 96 | 96 | 97 | 2402 | 100 |
1C2G筐咧;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 20 | 509 | 38.11 | 3 | 96 | 97 | 98 | 1715 | 100 |
2C2G噪矛;新節(jié)點(diǎn)量蕊;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 50 | 371 | 129.5 | 102 | 200 | 203 | 298 | 2023 | 100 |
1C2G;原節(jié)點(diǎn)艇挨;1號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 50 | 472 | 104.12 | 100 | 195 | 197 | 202 | 3056 | 100 |
1C2G残炮;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 50 | 446 | 110.3 | 100 | 197 | 199 | 297 | 1827 | 94 |
- 新節(jié)點(diǎn)在并發(fā)1~5之間達(dá)到CPU100%缩滨,QPS最高表現(xiàn)也在這之間達(dá)到(理論上會略高于526)势就,表現(xiàn)確實(shí)很拉垮。脉漏。苞冯。
- 原節(jié)點(diǎn)在并發(fā)1~5之間達(dá)到CPU100%,QPS最高表現(xiàn)也在這之間達(dá)到(理論上會略高于660/624)侧巨。
- CPU未打滿時(shí)舅锄,隨著并發(fā)度提高,QPS司忱、CPU占用率也隨之增長巧娱,響應(yīng)耗時(shí)保持穩(wěn)定碉怔;
- CPU打滿后,隨著并發(fā)度提高禁添,QPS先穩(wěn)定后逐步降低撮胧,響應(yīng)耗時(shí)逐步增大。
PHP8&Jit
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
2C2G老翘;新節(jié)點(diǎn)芹啥;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 1 | 83 | 11.13 | 11 | 17 | 18 | 19 | 158 | 30 |
2C2G;新節(jié)點(diǎn)铺峭;0號副本 | PHP-FPM8.0+OPcache | 新框架+健康檢查 | 1 | 84 | 11.04 | 11 | 17 | 18 | 19 | 88 | 30 |
2C2G墓怀;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 1 | 82 | 11.2 | 11 | 17 | 18 | 19 | 1674 | 38 |
2C2G卫键;新節(jié)點(diǎn)傀履;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 5 | 287 | 15.67 | 13 | 42 | 48 | 57 | 1682 | 100 |
2C2G;新節(jié)點(diǎn)莉炉;0號副本 | PHP-FPM8.0+OPcache | 新框架+健康檢查 | 5 | 290 | 15.66 | 12 | 42 | 48 | 58 | 171 | 100 |
2C2G钓账;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 5 | 288 | 15.87 | 12 | 42 | 48 | 59 | 1730 | 100 |
2C2G絮宁;新節(jié)點(diǎn)梆暮;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 20 | 272 | 70.67 | 94 | 103 | 107 | 192 | 1740 | 100 |
2C2G;新節(jié)點(diǎn)绍昂;0號副本 | PHP-FPM8.0+OPcache | 新框架+健康檢查 | 20 | 273 | 70.5 | 94 | 103 | 107 | 193 | 2081 | 100 |
2C2G啦粹;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 20 | 272 | 71.34 | 94 | 103 | 107 | 192 | 1807 | 100 |
2C2G窘游;新節(jié)點(diǎn)唠椭;0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 50 | 239 | 200.04 | 200 | 302 | 398 | 497 | 1998 | 100 |
2C2G;新節(jié)點(diǎn)忍饰;0號副本 | PHP-FPM8.0+OPcache | 新框架+健康檢查 | 50 | 251 | 195.91 | 199 | 302 | 395 | 489 | 2105 | 100 |
2C2G贪嫂;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 50 | 249 | 197.18 | 200 | 302 | 396 | 492 | 2183 | 100 |
2C2G喘批;新節(jié)點(diǎn);0號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查 | 100 | 216 | 454.79 | 403 | 797 | 901 | 1200 | 2664 | 100 |
2C2G铣揉;新節(jié)點(diǎn)饶深;0號副本 | PHP-FPM8.0+OPcache | 新框架+健康檢查 | 100 | 225 | 438.31 | 404 | 746 | 896 | 1193 | 2542 | 100 |
2C2G;新節(jié)點(diǎn)逛拱;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 100 | 222 | 444.76 | 407 | 744.9 | 892 | 1099 | 2443 | 100 |
- PHP8.0較比7.4在業(yè)務(wù)代碼不動的情況下(基于7.4及之前語法)沒有直接的性能提升敌厘;
- CPU消耗大頭不在opcache轉(zhuǎn)machine code環(huán)節(jié)(想想也是);
- PHP8.0+Jit目前無法帶來并發(fā)和性能表現(xiàn)的提升朽合。
IO堵塞次數(shù)
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
2C2G俱两;新節(jié)點(diǎn)饱狂;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 1 | 156 | 2.71 | 6 | 6 | 6 | 8 | 198 | 30 |
2C2G;新節(jié)點(diǎn)宪彩;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯 | 1 | 97 | 9.72 | 10 | 10 | 11 | 13 | 27 | 35 |
2C2G休讳;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯*5 | 1 | 75 | 12.58 | 12 | 13 | 14 | 16 | 1607 | 27 |
2C2G尿孔;新節(jié)點(diǎn)俊柔;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+復(fù)雜邏輯 | 1 | 82 | 11.2 | 11 | 17 | 18 | 19 | 1674 | 38 |
2C2G;新節(jié)點(diǎn)活合;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 5 | 508 | 9.09 | 6 | 8 | 41 | 48 | 1653 | 99 |
2C2G雏婶;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯 | 5 | 297 | 15.68 | 10 | 44 | 51 | 60 | 2046 | 100 |
2C2G白指;新節(jié)點(diǎn)留晚;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯*5 | 5 | 282 | 16.51 | 13 | 34 | 43 | 53 | 1809 | 98 |
2C2G;新節(jié)點(diǎn)告嘲;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+復(fù)雜邏輯 | 5 | 288 | 15.87 | 12 | 42 | 48 | 59 | 1730 | 100 |
2C2G错维;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 20 | 451 | 42.92 | 8 | 93 | 94 | 96 | 1843 | 100 |
2C2G状蜗;新節(jié)點(diǎn)需五;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯 | 20 | 275 | 70.91 | 94 | 101 | 104 | 191 | 1740 | 100 |
2C2G;新節(jié)點(diǎn)轧坎;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯*5 | 20 | 269 | 72.79 | 92 | 101 | 105 | 188 | 1809 | 100 |
2C2G宏邮;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+復(fù)雜邏輯 | 20 | 272 | 71.34 | 94 | 103 | 107 | 192 | 1807 | 100 |
2C2G缸血;新節(jié)點(diǎn)蜜氨;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 50 | 386 | 126.52 | 103 | 199 | 202 | 296 | 1989 | 100 |
2C2G;新節(jié)點(diǎn)捎泻;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯 | 50 | 247 | 197.5 | 199 | 299 | 303 | 404 | 2079 | 100 |
2C2G飒炎;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯*5 | 50 | 246 | 200.26 | 199 | 298 | 301 | 400 | 2067 | 100 |
2C2G笆豁;新節(jié)點(diǎn)郎汪;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+復(fù)雜邏輯 | 50 | 249 | 197.18 | 200 | 302 | 396 | 492 | 2183 | 100 |
2C2G;新節(jié)點(diǎn)闯狱;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+健康檢查 | 100 | 357 | 273.75 | 292 | 399 | 473.65 | 510 | 2089 | 100 |
2C2G煞赢;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯 | 100 | 233 | 424.72 | 402 | 602 | 697 | 897 | 2389 | 100 |
2C2G哄孤;新節(jié)點(diǎn)照筑;0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+簡單邏輯*5 | 100 | 226 | 438.53 | 403 | 604 | 699 | 852.98 | 2417 | 100 |
2C2G;新節(jié)點(diǎn);0號副本 | PHP-FPM8.0+OPcache+JIt | 新框架+復(fù)雜邏輯 | 100 | 222 | 444.76 | 407 | 744.9 | 892 | 1099 | 2443 | 100 |
- 邏輯中不同程度的IO會導(dǎo)致單次請求的響應(yīng)耗時(shí)增加凝危,但對CPU的占用率影響較胁ǘ怼;
- 請求響應(yīng)耗時(shí)高阻塞IO較比低阻塞IO普遍增加蛾默;
- 并發(fā)度未將CPU打滿時(shí)懦铺,高阻塞IO較比低阻塞IO的QPS表現(xiàn)要低;
- 當(dāng)并發(fā)度提升將CPU打滿后趴生,高阻塞IO較比低阻塞IO的QPS表現(xiàn)幾乎一致
PDO長連接
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
1C2G阀趴;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 1 | 139 | 6.56 | 5 | 6 | 6 | 15 | 2112 | 40 |
1C2G苍匆;原節(jié)點(diǎn)刘急;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 1 | 207 | 4.23 | 3 | 4 | 4 | 9 | 1337 | 45 |
1C2G;原節(jié)點(diǎn)浸踩;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 2 | 241 | 7.33 | 5 | 6 | 12 | 33 | 1077 | 83 |
1C2G叔汁;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 2 | 356 | 4.62 | 3 | 4 | 6 | 22 | 1060 | 91 |
1C2G检碗;原節(jié)點(diǎn)据块;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 5 | 274 | 16.37 | 5 | 66 | 74 | 86 | 1722 | 100 |
1C2G;原節(jié)點(diǎn)折剃;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 5 | 427 | 10.33 | 3 | 9 | 67 | 73 | 1293 | 100 |
1C2G另假;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 20 | 265 | 73.19 | 93 | 103 | 196 | 302 | 1778 | 88 |
1C2G怕犁;原節(jié)點(diǎn)边篮;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 20 | 393 | 49.31 | 12 | 97 | 100 | 103 | 1742 | 95 |
1C2G;原節(jié)點(diǎn)奏甫;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 50 | 253 | 195.05 | 198 | 300 | 398 | 599.79 | 1914 | 88 |
1C2G戈轿;原節(jié)點(diǎn);2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 50 | 345 | 142.96 | 102 | 200 | 202 | 300 | 2136 | 92 |
1C2G阵子;原節(jié)點(diǎn)思杯;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+短連 | 100 | 241 | 401.15 | 397 | 601 | 705 | 1203.1 | 2644 | 99 |
1C2G;原節(jié)點(diǎn)挠进;2號副本 | PHP-FPM7.4+OPcache | 新框架+簡單邏輯+長連 | 100 | 325 | 303.06 | 299 | 496 | 501 | 701 | 2205 | 100 |
網(wǎng)絡(luò)連接資源復(fù)用較比不復(fù)用在當(dāng)前業(yè)務(wù)特點(diǎn)下能帶來:
- 提升35~55%QPS色乾;
- 降低25~37%響應(yīng)耗時(shí)。
框架截?cái)?/h2>
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
1C2G领突;原節(jié)點(diǎn)暖璧;3號副本 | PHP-FPM7.4+OPcache | 入口文件直接返回 | 20 | 6505 | 2.72 | 1 | 1 | 2 | 68 | 1774 | 100 |
1C2G;原節(jié)點(diǎn)攘须;3號副本 | PHP-FPM7.4+OPcache | 入口文件解析完請求 | 20 | 5956 | 2.72 | 1 | 1 | 1 | 69 | 1832 | 100 |
1C2G漆撞;原節(jié)點(diǎn);3號副本 | PHP-FPM7.4+OPcache | 引入自動加載之后 | 20 | 4341 | 3.61 | 1 | 1 | 2 | 77 | 2108 | 100 |
1C2G于宙;原節(jié)點(diǎn)浮驳;3號副本 | PHP-FPM7.4+OPcache | 加載項(xiàng)目配置之后 | 20 | 2278 | 8.16 | 1 | 2 | 86 | 89 | 1101 | 100 |
1C2G;原節(jié)點(diǎn)捞魁;3號副本 | PHP-FPM7.4+OPcache | 加載底層配置之后 | 20 | 849 | 23.04 | 2 | 94 | 94 | 95 | 1867 | 100 |
1C2G至会;原節(jié)點(diǎn);3號副本 | PHP-FPM7.4+OPcache | 注冊全部請求接口之后 | 20 | 630 | 30.97 | 2 | 95 | 96 | 97 | 1899 | 100 |
1C2G谱俭;原節(jié)點(diǎn)奉件;3號副本 | PHP-FPM7.4+OPcache | 健康檢查完整處理 | 20 | 516 | 37.62 | 3 | 96 | 97 | 98 | 1878 | 77 |
磨損主要發(fā)生環(huán)節(jié):
- 引入自動加載(composer autoload);
- 加載項(xiàng)目配置昆著;
- 加載底層配置县貌。
優(yōu)化方向
短連改長連
將請求MySQL、Redis的連接模式改成長連接凑懂,將連接周期由請求級別延伸至FPM進(jìn)程級別煤痕,以此減少連接創(chuàng)建銷毀操作降低CPU占用、減少響應(yīng)耗時(shí)提升性能整體表現(xiàn)接谨。
但考慮到:
- MySQL摆碉、Redis連接數(shù)將幾乎與FPM開啟的Work進(jìn)程數(shù)量一致;
- 多項(xiàng)目脓豪、多組共用MySQL巷帝、Redis;
- 短連模式下扫夜,QPS過高反而會帶來本地端口用盡的問題(具體見本文最后)楞泼。
決定暫時(shí)不采用此方案。
緩存項(xiàng)目與底層配置
將原先每次請求都讀取多個(gè)ini配置文件并解析結(jié)構(gòu)改造成初始化時(shí)讀取并解析然后回寫為php數(shù)組文件:
- 避免config map的性能影響(原先這些ini配置都是通過config map掛載進(jìn)項(xiàng)目)历谍;
- 節(jié)省ini配置解析成本(php文件直接借用php本身opcache现拒、jit優(yōu)化就足夠)。
我將這個(gè)優(yōu)化做到了新框架的后續(xù)版本中望侈,并且壓測驗(yàn)證:
資源情況 | 程序情況 | 接口復(fù)雜度 | 并發(fā)度 | QPS | AVG | 50TH | 90TH | 95TH | 99TH | MAX | CPU(峰值) |
---|---|---|---|---|---|---|---|---|---|---|---|
1C2G印蔬;原節(jié)點(diǎn);4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 1 | 480 | 1.6 | 2 | 2 | 2 | 2 | 220 | 77 |
1C2G脱衙;原節(jié)點(diǎn)侥猬;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 1 | 705 | 1.05 | 1 | 1 | 2 | 2 | 1775 | 79 |
1C2G;原節(jié)點(diǎn)捐韩;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 2 | 619 | 2.55 | 2 | 2 | 2 | 35 | 2526 | 100 |
1C2G退唠;原節(jié)點(diǎn);4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 2 | 1083 | 1.54 | 1 | 1 | 2 | 26 | 2275 | 100 |
1C2G荤胁;原節(jié)點(diǎn)瞧预;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 5 | 659 | 6.8 | 2 | 2 | 72 | 77 | 2409 | 100 |
1C2G;原節(jié)點(diǎn);4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 5 | 1060 | 4.36 | 1 | 2 | 2 | 72 | 2335 | 100 |
1C2G垢油;原節(jié)點(diǎn)盆驹;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 20 | 530 | 37.09 | 3 | 96 | 97 | 98 | 2398 | 100 |
1C2G;原節(jié)點(diǎn)滩愁;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 20 | 970 | 20.18 | 2 | 93 | 94 | 95 | 2601 | 100 |
1C2G躯喇;原節(jié)點(diǎn);4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 50 | 469 | 105.58 | 100 | 196 | 198 | 231.99 | 2799 | 100 |
1C2G硝枉;原節(jié)點(diǎn)廉丽;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 50 | 946 | 52.22 | 90 | 98 | 99 | 103 | 2901 | 100 |
1C2G;原節(jié)點(diǎn)妻味;4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+不緩存配置 | 100 | 415 | 239.43 | 202 | 394 | 400 | 598 | 3000 | 100 |
1C2G正压;原節(jié)點(diǎn);4號副本 | PHP-FPM7.4+OPcache | 新框架+健康檢查+緩存配置 | 100 | 920 | 107.89 | 100 | 195 | 199 | 289 | 2609 | 100 |
緩存配置較比不緩存對沒有連接和阻塞IO的邏輯能帶來:
- 提升46~121%QPS责球;
- 降低34~54%響應(yīng)耗時(shí)蔑匣;
- 并發(fā)度越高,效果越明顯(在可承受的并發(fā)度范圍內(nèi))棕诵。
我也對帶上不同程度業(yè)務(wù)邏輯的場景進(jìn)行了測試裁良;
簡單邏輯下緩存配置較比不緩存能帶來:
- 提升9~14%QPS;
- 降低9~12%響應(yīng)耗時(shí)校套;
復(fù)雜邏輯下緩存配置較比不緩存能帶來:
- 提升4~17%QPS价脾;
- 降低5~14%響應(yīng)耗時(shí);
換運(yùn)行模式
如果前面兩者都不可用或者不能滿足需要的時(shí)候笛匙,可以考慮更換當(dāng)前這種FPM的運(yùn)行模式侨把,改用Cli+異步模型:
- 天生可以使用MySQL、Redis妹孙、HTTP等連接池技術(shù)秋柄,又不需要當(dāng)心連接數(shù)過多的問題;
- 進(jìn)一步減少代碼解釋執(zhí)行過程的消耗蠢正,Opcache和Jit技術(shù)可以進(jìn)一步發(fā)揮作用骇笔;
- 異步搭配yield/Fiber,或是swoole封裝的異步庫充分利用CPU嚣崭,提升單接口響應(yīng)效率笨触。
但這樣無疑是存在較高的成本和風(fēng)險(xiǎn)的:
- 現(xiàn)有的框架、庫包都是基于同步阻塞封裝的雹舀,異步可能帶來并發(fā)爭競隱患芦劣;
- FPM同步阻塞模型犧牲一定性能帶來的是開發(fā)效率和門檻的優(yōu)勢,如果換成異步模型说榆,對開發(fā)人員和業(yè)務(wù)無疑會帶來更高的門檻和風(fēng)險(xiǎn)虚吟;
- 類似swoole+異步協(xié)程其實(shí)幾乎都相當(dāng)于換了大半個(gè)語言了寸认。
整體結(jié)論
- 目前1C2G在壓測環(huán)境一般的邏輯都可以達(dá)到250甚至更高了,暫時(shí)滿足我們的業(yè)務(wù)需求(更高的性能表現(xiàn)可以通過擴(kuò)展副本來實(shí)現(xiàn))串慰;
- 還有很多的優(yōu)化方案和空間废麻,但考慮到團(tuán)隊(duì)目前的情況和方案的成本與風(fēng)險(xiǎn),暫時(shí)不開展這類方案模庐。
短連單副本QPS過高的問題
當(dāng)前的系統(tǒng)設(shè)置為:
- 本地可用客戶端端口范圍:32768~60999
- time wait狀態(tài)快速回收和重用:沒有權(quán)限,但根據(jù)現(xiàn)象觀察應(yīng)該是60s
當(dāng)我調(diào)大CPU資源為2C壓測一個(gè)簡單邏輯(每個(gè)請求會創(chuàng)建一個(gè)MySQL連接油宜,請求結(jié)束就主動close連接)時(shí)掂碱,QPS達(dá)到500上下,但最后幾秒會出現(xiàn)本地端口用盡的問題慎冤。