大家好,我是程序員魚(yú)皮。
之前我?guī)Т蠹易龅? 項(xiàng)目 ,用戶可以在線制作、分享、使用代碼生成器~
![]()
這次的系列教程中,我專門(mén)用了 4 個(gè)小時(shí)的直播,給大家?guī)?lái)了一場(chǎng)極致的 性能優(yōu)化 “盛宴”。
很多同學(xué)由于沒(méi)有實(shí)習(xí)或工作經(jīng)歷,可能沒(méi)有接觸過(guò)性能優(yōu)化,但這卻是能區(qū)分程序員水平的重要技能。
為什么這么說(shuō)?
舉個(gè)例子:
優(yōu)秀的程序員,能用 1 臺(tái)機(jī)器滿足 10000 個(gè)用戶的使用需求,如果滿足不了,首先想到的是繼續(xù)去優(yōu)化。
而一般的程序員,用 1 臺(tái)機(jī)器可能只能滿足 1000 個(gè)用戶的使用需求,如果滿足不了,就要加機(jī)器、加資源。現(xiàn)實(shí)往往是沒(méi)有資源給你加。
怎么區(qū)分一個(gè)程序員有沒(méi)有性能優(yōu)化經(jīng)驗(yàn)?zāi)兀?/p>
就先問(wèn)大家一個(gè)問(wèn)題吧:一臺(tái)部署了 Tomcat 的服務(wù)器,每秒最多能處理多少個(gè)請(qǐng)求?
下面給大家簡(jiǎn)單分享下我直播中的性能優(yōu)化過(guò)程,答案也將在最后揭曉。
性能優(yōu)化實(shí)踐
要優(yōu)化的是一個(gè)后端查詢接口,功能是查詢出主頁(yè)要展示的分頁(yè)數(shù)據(jù)列表,邏輯很簡(jiǎn)單,就是數(shù)據(jù)庫(kù)分頁(yè)查詢而已。
如下圖:
![]()
首先我們往數(shù)據(jù)庫(kù)里插入 10 萬(wàn)條數(shù)據(jù),然后打開(kāi)瀏覽器控制臺(tái),觀察 10 次請(qǐng)求的響應(yīng)耗時(shí),平均是 700 毫秒:
![]()
1)首先,我嘗試優(yōu)化了數(shù)據(jù)查詢的 SQL 語(yǔ)句,讓它只查詢需要返回給前端的數(shù)據(jù),減少數(shù)據(jù)量。
優(yōu)化后的接口平均耗時(shí)是 500 多毫秒,大概響應(yīng)時(shí)長(zhǎng)縮短了 1 / 4:
![]()
使用 JMeter 進(jìn)行壓力測(cè)試,每秒啟動(dòng) 1000 個(gè)線程,總共啟動(dòng) 1 萬(wàn)個(gè)線程發(fā)送請(qǐng)求,在異常率 0% 的前提下,測(cè)試結(jié)果得到的 qps 為 20,這顯然不是一個(gè)很好的成績(jī)。
![]()
2)進(jìn)一步優(yōu)化,使用性能更高的 Redis 分布式緩存。將分頁(yè)查詢結(jié)果作為 JSON 字符串寫(xiě)入緩存,再次查詢的時(shí)候直接讀取就行。
結(jié)果響應(yīng)時(shí)長(zhǎng)直接縮短到了平均 20 毫秒!縮短了 25 倍!
第一個(gè)請(qǐng)求是加載緩存的,所以較慢。
有緩存的情況下,壓力測(cè)試得到的 qps 是 114.6,提升了 5 倍多!
![]()
可見(jiàn)緩存還是猛啊,讀多寫(xiě)少、更新頻率低、訪問(wèn)頻率高的數(shù)據(jù),非常適合使用緩存。
還能進(jìn)一步優(yōu)化么?
3)當(dāng)然能!使用比分布式緩存更快的本地緩存,直接從當(dāng)前服務(wù)器內(nèi)存讀取數(shù)據(jù),更快~
用瀏覽器控制臺(tái)測(cè)試響應(yīng)時(shí)長(zhǎng),幾乎沒(méi)有變化(因?yàn)槲覝y(cè)試過(guò)程中,Redis 也是本地啟動(dòng)的):
![]()
進(jìn)行壓力測(cè)試,發(fā)現(xiàn) qps 略有提升,大概 10% 左右吧:
![]()
本地緩存按道理來(lái)說(shuō)已經(jīng)是最快的讀取方式了,難道這就已經(jīng)優(yōu)化到極限了么?
當(dāng)然沒(méi)有!
4)雖然 I / O 難以繼續(xù)優(yōu)化了,但我們可以優(yōu)化程序的計(jì)算邏輯、節(jié)約 CPU 資源。
比如我修改緩存的數(shù)據(jù)類(lèi)型,不再寫(xiě)入 JSON 格式的緩存了,直接用 JDK 原生的序列化方式去保存對(duì)象,這樣讀取的時(shí)候也不需要把 JSON 轉(zhuǎn)為對(duì)象。
優(yōu)化這個(gè)邏輯后,響應(yīng)時(shí)長(zhǎng)大幅度減少!平均 8 毫秒左右:
![]()
沒(méi)想到吧,看似不起眼的 JSON 轉(zhuǎn)換操作,這么影響性能?
壓力測(cè)試的結(jié)果更恐怖了,吞吐量接近 16000,直接提升了 100 多倍!
![]()
真是不測(cè)不知道,一測(cè)嚇一跳。
問(wèn)題來(lái)了,還能繼續(xù)優(yōu)化么?
當(dāng)然可以!
5)除了業(yè)務(wù)邏輯層,我們還可以優(yōu)化請(qǐng)求層。比如修改 Tomcat 服務(wù)器的配置,增大工作線程數(shù)和最大線程連接數(shù)。
稍微改 2 行配置,吞吐量就提高了 1 / 5 左右,接近 19000!相比最開(kāi)始的 qps 20 提升了近千倍!
![]()
這。。這次到極限了么?
我怎么知道啊!肯定還是需要自己測(cè)試這個(gè)極限到底在哪里!
如何測(cè)試呢?
6)我們可以編寫(xiě)一個(gè)沒(méi)有任何業(yè)務(wù)邏輯,直接返回 "ok" 字符串的空接口。
每秒啟動(dòng) 10 萬(wàn)個(gè)線程來(lái)測(cè)試,得到的 qps 為 36000+,又提高了整整一倍!
![]()
ok,沒(méi)有任何邏輯的接口 qps 是這個(gè)數(shù),那么你再怎么優(yōu)化業(yè)務(wù)邏輯,性能的極限也不會(huì)超過(guò)這個(gè)值。
那么,還有辦法繼續(xù)優(yōu)化么?
當(dāng)然可以!
7)因?yàn)檫@只是 Tomcat 服務(wù)器 + Spring MVC 框架的極限,如果我們用別的技術(shù)呢?
![]()
這里我就拋磚引玉,大家感興趣的話,可以找個(gè)項(xiàng)目中的查詢接口、用我上面提到的方法優(yōu)化下。
回到最開(kāi)始的問(wèn)題 “一臺(tái)部署了 Tomcat 的服務(wù)器,每秒最多能處理多少個(gè)請(qǐng)求?”
其實(shí)這個(gè)答案是 無(wú)解 ,因?yàn)槿鄙倭俗钪匾臏y(cè)試條件、測(cè)試環(huán)境和測(cè)試基準(zhǔn),比如是在幾核幾 G、帶寬多少的機(jī)器上測(cè)試呢?不同的測(cè)試環(huán)境,測(cè)試結(jié)果肯定不同。性能優(yōu)化效果一定要以實(shí)際測(cè)試結(jié)果為準(zhǔn),下次遇到這種問(wèn)題的時(shí)候,別被面試官唬住了哦~
以上就是本期分享,時(shí)間有限文章就只能講這么多了,大家如果對(duì)這個(gè)項(xiàng)目、這次的性能優(yōu)化完整教程感興趣,歡迎 學(xué)習(xí)。
這個(gè)項(xiàng)目視頻教程接近 40 小時(shí),文字教程十幾萬(wàn)字,我付出了大量的頭發(fā)精力,也保證絕對(duì)是一個(gè)很能打的項(xiàng)目~
![]()
點(diǎn)擊下方關(guān)注魚(yú)皮,獲取免費(fèi)編程學(xué)習(xí)路線、簡(jiǎn)歷模板、面試題解、AI 知識(shí)庫(kù)、項(xiàng)目教程、交流群。
一些對(duì)大家有用的資源:
100+ 編程學(xué)習(xí)路線 / 實(shí)戰(zhàn)項(xiàng)目 / 求職指導(dǎo)
100+ 簡(jiǎn)歷模板
300+ 企業(yè)面試題庫(kù) mianshiya.com
500+ AI 資源大全
1 對(duì) 1 模擬面試
動(dòng)畫(huà)學(xué)算法教程
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.