3年以下的后端開(kāi)發(fā)者

以下文章轉(zhuǎn)載自知乎,暗滅-京華九月秋近寒,浮沉半生影長(zhǎng)單.

【修真院“善良”系列之十七】請(qǐng)拿好這支時(shí)間之箭

暗滅

京華九月秋近寒,浮沉半生影長(zhǎng)單

適用讀者:3年以下的后端開(kāi)發(fā)者

文章目錄:

1.為什么要做性能優(yōu)化

2.性能優(yōu)化之前,先定位問(wèn)題

3.Nginx和Tomcat

4.Controller和Service又做了什么

5.Memcache和DB做了什么

6.聽(tīng)說(shuō)他們久經(jīng)沙場(chǎng)

? 一 為什么要做性能優(yōu)化

“這破網(wǎng)站慢死了。”果凍咬著牙說(shuō),“這些程序員都是干嘛吃的 ?”

毛毛看著果凍笑,沒(méi)說(shuō)話,畢竟果凍說(shuō)的破網(wǎng)站是“修真院自己的官網(wǎng)”,畢竟果凍說(shuō)的這些“干嘛吃的”程序員就在他們UE組對(duì)面。果凍是一個(gè)萌妹子,怎么說(shuō)都行,毛毛做為一個(gè)PM,可是經(jīng)常注意培宇桌子下面常備兩塊板磚的。

培宇有一點(diǎn)點(diǎn)臉紅,果凍對(duì)培宇是一直有偏見(jiàn)的,畢竟當(dāng)眾表白被拒是誰(shuí)都難以接受的。自那以后,本著“沒(méi)有打擊培宇的機(jī)會(huì),就創(chuàng)造打擊培宇的機(jī)會(huì)”的原則,果凍讓培宇生生見(jiàn)識(shí)到了什么叫做“由愛(ài)生恨兩重天”。

旁邊的小馬哥不干了,當(dāng)場(chǎng)就“哐“的一下拍桌子,整個(gè)二樓的人都嚇了一跳,看著小馬哥。

果凍也一樣嚇了一跳,回過(guò)神來(lái)之后就當(dāng)場(chǎng)發(fā)飚了:”偉江你要死嗎?“

偉江本來(lái)想說(shuō)”你行你上啊“,但是看了看果凍漸漸變冷的眼神,終究還是說(shuō)不出口,可是氣氛一度很尬啊,只好小聲說(shuō)了一句:”我去找老大解決去。。。。。?!?/p>

所有人:”。。。。?!?/p>

培宇笑的不行:”偉江就該這么有霸氣,在果凍的淫威下終于爆發(fā)了,一怒而起,然后一溜煙的跑去找老大了~“

二 性能優(yōu)化之前,先定位問(wèn)題

說(shuō)到性能之前,先談量化。

說(shuō)網(wǎng)站慢,那是普通用戶(hù)的說(shuō)的話。

而對(duì)程序員來(lái)講,必須是到多少M(fèi)S。

多少M(fèi)S才算慢?通常來(lái)說(shuō),人的眼睛對(duì)于200MS以上的時(shí)延是有反應(yīng)的,所以一般而言,一整個(gè)頁(yè)面都應(yīng)該在200MS之內(nèi)完成。

對(duì)于復(fù)雜的請(qǐng)求,可以再稍微慢一點(diǎn),畢竟大家還能忍,能忍的程度跟網(wǎng)站的價(jià)值成正比。反正我看小黃片的時(shí)候是挺能忍的~

簡(jiǎn)單的用戶(hù)個(gè)人信息這種請(qǐng)求,應(yīng)該在50MS左右,List的數(shù)據(jù),差不多在100MS左右。這是比較正常的數(shù)據(jù)。

以上這些全是暗滅大人罵偉江的原話。

”所以你做為一個(gè)程序員,過(guò)來(lái)跟我說(shuō)網(wǎng)站慢?你應(yīng)該直接告訴我說(shuō)現(xiàn)在哪一個(gè)請(qǐng)求慢,慢到多少M(fèi)S,應(yīng)該達(dá)到多少M(fèi)S。“

暗滅大人一邊狠狠的罵了偉江一頓,一邊繼續(xù)在QQ上教小師妹學(xué)習(xí):“小師妹啊,我聽(tīng)說(shuō)最近剛上映了一部電影叫做《人民的名義》,我看了看,感覺(jué)對(duì)于寫(xiě)代碼很有幫助啊,強(qiáng)烈推薦給你看,這樣,剛好有人買(mǎi)了兩張電影票給我,我?guī)阋黄鹑W(xué)習(xí)一下吧。”

偉江趕緊的拿出手機(jī)來(lái),兩張票買(mǎi)后,然后截圖發(fā)給老大。

暗滅大人看到截圖,這才滿(mǎn)意,跟小師妹又回了句:“稍等啊,我要開(kāi)個(gè)董事會(huì)。”

“拿白板來(lái)!”老大說(shuō)。

首先,果凍朝你設(shè)了一箭。你接到了果凍射過(guò)來(lái)的這支愛(ài)之箭,看了看箭上附的小紙條,寫(xiě)的是什么內(nèi)容,按果凍的指示把她想要做的事給做完了,然后把結(jié)果又放到小紙條上,再扔回給了果凍,果凍收到箭之后,打開(kāi)看完。

這是一個(gè)完整的Http請(qǐng)求過(guò)程。

然后老大在白板上這么畫(huà)了一下。

這表示,對(duì)于一個(gè)網(wǎng)絡(luò)請(qǐng)求來(lái)說(shuō),第一個(gè)層面,你需要知道的時(shí)間的損耗可以分解成三大部分。

第一部分前端的響應(yīng),一般包括解析和渲染,這部分的性能跟前端的代碼,前端硬件有關(guān)系。

第二部分就是網(wǎng)絡(luò)延遲,這部分的代碼正常來(lái)講是在8~16MS左右,是的,Http請(qǐng)求就是差不多這個(gè)性能,如果是WebSocket幾乎可以做到零延遲,有暗滅大人當(dāng)年寫(xiě)的多人在線掃雷(http://game.ptteng.com支持多人在線玩掃雷,一個(gè)人點(diǎn)錯(cuò)所有人完蛋的惡趣味)為證。

第三部分就是服務(wù)器端的響應(yīng),我們說(shuō)的是網(wǎng)站慢,一般而言,也就是主要在這里,要做性能優(yōu)化的地方,基本上也是看這里。

偉江聽(tīng)的正津津有味,突然間發(fā)現(xiàn)老大已經(jīng)轉(zhuǎn)身要走了,趕緊拿出手機(jī)來(lái)又訂了一個(gè)燭光晚餐。

“老大,老大,我怎么才能知道每一段時(shí)間間隔多久呢?在哪可以看得到?。俊?/p>

“F12,F(xiàn)iddle都行啊,這種叫端到端的響應(yīng)時(shí)間,服務(wù)器端的響應(yīng)時(shí)間啊,要看Nginx的Access.log.”老大滿(mǎn)意的點(diǎn)了點(diǎn)頭:“偉江的學(xué)習(xí)態(tài)度很好嘛,不像培宇,太笨,又不肯用心?!?/p>

“Access.log里會(huì)記錄服務(wù)器端自己的響應(yīng)時(shí)間,這是后端查看性能的重要依據(jù),也是找運(yùn)維背鍋的必備技能。一旦你發(fā)現(xiàn)服務(wù)器端的響應(yīng)時(shí)間沒(méi)問(wèn)題,而端到端的響應(yīng)有問(wèn)題,那就百分百的是網(wǎng)絡(luò)問(wèn)題了,可以直接找運(yùn)維同學(xué)背鍋了。”

“這些是做性能優(yōu)化之前必須要弄明白的,問(wèn)題到底出在哪兒呢?否則怎么做性能優(yōu)化?所以解決性能的問(wèn)題,跟你泡妹子是一樣的,要先脫掉妹子的外套,再脫掉外套里面的上衣,然后。?!?/p>

偉江擦了擦口水,說(shuō):“老大,如果確實(shí)是我們后端的問(wèn)題呢,前端響應(yīng)正常,網(wǎng)絡(luò)傳輸也正常,就是后端響應(yīng)出問(wèn)題,該怎么解決?”

三 .Nginx和Tomcat

“為什么要在前端掛一個(gè)Nginx,而不是直接用Tomcat呢?”

“你別管,總之好處多多了,不過(guò)是域名,還是跨域,還是防Ddos攻擊,Nginx都是利器,很好用?,F(xiàn)在就照著來(lái)。”

Nginx相當(dāng)于是一個(gè)大的總管,所有的請(qǐng)求都是先到Nginx這里來(lái),然后再發(fā)給后面的Tomcat,或者是Resin什么的。

后面的Tomcat像當(dāng)于是一個(gè)個(gè)漂亮女生宿舍的話:

所以Nginx就像當(dāng)于是女生宿舍的門(mén)衛(wèi)

對(duì)的??傊甆ginx很贊,我很喜歡。Nginx會(huì)記錄有所有的出入時(shí)間。

如果Nginx的耗時(shí)比較長(zhǎng),一般而言,問(wèn)題都不太會(huì)直接出在nginx身上,可以直接再去查T(mén)omcat/resin/jetty這些女生宿舍的崗了,哦,不是,去查看這些服務(wù)器的日志響應(yīng)時(shí)間了。

所以,Nginx和Tomcat之間的圖應(yīng)該是這樣的。

Tomcat本身也會(huì)有一個(gè)日志記錄,也是Access.log,其他的叫別的什么日志無(wú)所謂了,反正從名字來(lái)看,就是進(jìn)女生宿舍的時(shí)間和離開(kāi)的時(shí)間--那群Tomcat的研發(fā)人員一定是做了很多的實(shí)地調(diào)研才能有如此神似的命名。

那么鍋就繼續(xù)甩給了Tomcat。Tomcat之后是什么呢?基本上就全部是Java人員寫(xiě)的代碼了。所以我們要不要往女生宿舍里偷偷看一眼?

可是最關(guān)鍵的就是女生宿舍吧,哪能只偷偷看一眼就走!”偉江有點(diǎn)不滿(mǎn)意。

四? .Controller和Service又做了什么

說(shuō)的沒(méi)錯(cuò),Tomcat里的時(shí)間其實(shí)還可以再分解的更細(xì)一些。第一個(gè)接受到響應(yīng)的就是Controller,而之前說(shuō)過(guò),Controller通常是用來(lái)控制Service的,你可以理解為,每一個(gè)Service就是一個(gè)漂亮妹子。

Controller就是一個(gè)宿舍的宿管員。就是少林足球里的包租婆,她來(lái)負(fù)責(zé)管理這些小妹妹做什么事兒。

Controller依次調(diào)用女生Service1,女生Service2,女生Service3~然后再把結(jié)果返回給你。

所以Tomcat響應(yīng)的時(shí)間可以分為:

1.Controller的處理時(shí)間

2.Service的調(diào)用時(shí)間

3.返回結(jié)果的處理時(shí)間

controller本身的處理事情,一般都會(huì)是在開(kāi)始和結(jié)束各打一條毫秒數(shù)這是所有的業(yè)務(wù)邏輯處理的總時(shí)間。調(diào)用各Service的時(shí)間包含網(wǎng)絡(luò)傳輸和Service的響應(yīng)時(shí)間。返回結(jié)果的時(shí)間一般都是解析成Json的時(shí)間。

生成Json的時(shí)間通常很短,很短,網(wǎng)絡(luò)傳輸?shù)臅r(shí)間說(shuō)不好,RMI的話,除第一次建立連接外,幾乎可以忽略不計(jì),但是一個(gè)Controller里調(diào)用上百次的話,速度就會(huì)慢起來(lái)。Http無(wú)疑是最慢的,單純建立就要花幾MS,對(duì)性能有更高要求的話,用Thrift和ProtocolBuffer等。

而我一般都喜歡用RMI,不喜歡異構(gòu)的東西,Http又引入了額外的負(fù)擔(dān),所以比較喜歡用Tuscany直接調(diào)用RMI。

所以性能優(yōu)化的重點(diǎn),就是要弄明白,如果一個(gè)大老爺們,比如說(shuō)培宇,進(jìn)了女生宿舍之后,總共花了500多MS的時(shí)間,他在包租婆那里花了多長(zhǎng)時(shí)間?他跑到妹子1的床前花了多久?和妹子1在一起同幾MS?跑到妹子2的床前是多久?在妹子2那里花了幾MS?

這些數(shù)據(jù)都要清清楚楚,還是要用圖來(lái)表明一下。

這個(gè)就是小培宇。如果他爬上每一個(gè)妹子的床之后都回來(lái)找包租婆登記一下,就是這樣的。

如果他爬了一個(gè)妹子的床,然后趕緊的去爬了另一個(gè)妹子的床,這就是另一個(gè)服務(wù)調(diào)用服務(wù)的過(guò)程了。

這兩種方式的優(yōu)劣,我們隨后再說(shuō)。

如果他進(jìn)去之后變成了8個(gè)小培宇,每個(gè)小培宇分別去上8個(gè)妹子的床,這就是多線程和異步。

如果他自己帶了一個(gè)小黑板,啪啪啪寫(xiě)上自己的地址,然后就走。8個(gè)妹子看到地址之后各自去找小培宇,這就是消息隊(duì)列。

總之,先不討論這么復(fù)雜的東西,我們就只說(shuō),培宇是一個(gè)妹子一個(gè)妹子的上。。。。。床。

那么,Controller那里應(yīng)該怎么統(tǒng)計(jì)時(shí)間呢?

一般而言,我們會(huì)手寫(xiě)一個(gè)AOP的Util。并不會(huì)在Controller里手寫(xiě)StartAt和EndAt。

這個(gè)Aop寫(xiě)起來(lái)很容易,正常來(lái)講,會(huì)在代碼里這么寫(xiě):

如果超過(guò)了50MS,記錄日志,入?yún)ⅲ瑫r(shí)間。

如果不超過(guò)50MS,不記錄。

這個(gè)50MS依據(jù)每個(gè)人的身體情況,哦不,依據(jù)每個(gè)應(yīng)用的情況來(lái)自行設(shè)置。

所以,到了這里,你就會(huì)知道了,我們把果凍射來(lái)的愛(ài)之箭,已經(jīng)穿透了包租婆,到了女生宿舍,并且分解到了每一個(gè)床位的時(shí)間。

這就是一個(gè)分析和定位的過(guò)程,而通常就是在Controller的代碼里,一般我們都叫做WEB工程,在這里去用Aop來(lái)記錄第一個(gè)Service的響應(yīng)時(shí)間。

如果我們發(fā)現(xiàn)了,培宇在2號(hào)女生那兒花費(fèi)的時(shí)間特別長(zhǎng)呢?

? 五.Memcache和DB做了什么

“那就把培宇閹了!”偉江斬釘截鐵的說(shuō)。

“好的,現(xiàn)在就動(dòng)手。” 老大滿(mǎn)懷期待的看著他。

這得把培宇喊過(guò)來(lái),問(wèn)問(wèn)他在2號(hào)女生那里做什么了。

寫(xiě)到這里我必須得說(shuō),這是公開(kāi)版,公開(kāi)版只能說(shuō),培宇在約2號(hào)女生看電影。

內(nèi)部版,非公開(kāi)發(fā)生的,培宇做的事情就比較多了。。

好了,先說(shuō)看電影。

培宇說(shuō):乖,我們?nèi)タ措娪鞍伞?/p>

妹子說(shuō):好的,我要找找我的身份證。

這個(gè)時(shí)間發(fā)現(xiàn)身份證不在身邊,在老家,于是妹子說(shuō),乖,你等著,我去老家把身份證拿過(guò)來(lái)。

這就叫做直接從DB里拿數(shù)據(jù)。

所以時(shí)間性能的損耗,就在于是:培宇和妹子說(shuō)話,妹子回老家拿身份證。

大概的場(chǎng)景就是這樣的。

培宇說(shuō):乖,我們看電影去吧。

妹子說(shuō):好啊,好啊,等我,我回老家拿身份證,然后一個(gè)月過(guò)去了。

培宇和妹子想了想,還是沒(méi)辦法看電影。

第二次培宇又說(shuō):乖,我們看電影吧。

妹子說(shuō);好啊,好啊,等我,我回家拿身份證,然后一個(gè)月又過(guò)去了。

培宇和妹子再見(jiàn)面之后,想了想,還是沒(méi)辦法看電影。

上一篇講過(guò)Dao。其實(shí)Service里對(duì)于Dao的訪問(wèn)時(shí)間分析,也是這么記錄的。同理,如果你要用到多個(gè)Dao,可能是先回老家拿身份證,再去商場(chǎng)買(mǎi)件衣服等等等等。

而我們統(tǒng)計(jì)妹子去拿身份證的時(shí)間,也是同理可以用剛剛說(shuō)過(guò)的Aop的性能統(tǒng)計(jì)Util.

這樣一個(gè)Service處理事情的時(shí)間,就分成了本地運(yùn)算和獲取數(shù)據(jù)的時(shí)間。

通常本地運(yùn)算的時(shí)間會(huì)比較快,而獲取數(shù)據(jù)的時(shí)間會(huì)比較慢。

如果說(shuō)你發(fā)現(xiàn)了妹子總是回老家,而且時(shí)間剛好是一個(gè)月,你怎么辦?

給妹子提個(gè)醒,可不可以把身份證放到旁邊的衣柜里?這樣我們就可以直接從衣柜里拿身份證了啊。

這個(gè)衣柜,就叫做緩存。

而一般而言,我們的包租婆是不管妹子從哪拿身份證的,總之能接待好客人,呃,接待好培宇就行了。

所以如果要繼續(xù)區(qū)分,性能問(wèn)題。必須要知道,數(shù)據(jù)有沒(méi)有走緩存?從緩存中的數(shù)據(jù)取出來(lái)要多久?正常情況下應(yīng)該幾MS,為什么妹子花了20多MS?是不是柜子前面的人比較多?還是從床到柜子中間的路壞了?柜子是在哪里放著的?

妹子回老家取身份證,會(huì)不會(huì)堵車(chē)?

這些都是需要靠日志來(lái)記錄時(shí)間,也簡(jiǎn)單提醒一下,假設(shè)不是培宇一個(gè)人來(lái)呢。10000個(gè)人同時(shí)來(lái)呢?你必須得在日志里記錄一些關(guān)鍵信息,確保知道哪個(gè)時(shí)間是哪個(gè)老板,呃,哪個(gè)客戶(hù)的。

六.聽(tīng)說(shuō)他們久經(jīng)沙場(chǎng)

其實(shí)性能優(yōu)化有很多很多方案,不同的應(yīng)用場(chǎng)景,解決方案是不同的。但是最根本的就是要明白,時(shí)間倒底損耗在什么地方?

對(duì)于果凍來(lái)說(shuō),就是簡(jiǎn)單的射了一支愛(ài)之箭,后面做了哪些,是不需要知道的。

可是偉江就必須得明白,培宇對(duì)每一個(gè)女生宿舍的妹子都做了什么。在保安那里花了多久,在包租婆那里花了多久,在每一個(gè)女生床上花了多久,妹子從柜子里取身份證要多久,從老家取身份證又要多久。

我們一直說(shuō)的,一個(gè)程序員的真正工作的地方不在筆記本上,也不是在開(kāi)發(fā)環(huán)境,也不是在測(cè)試環(huán)境,而是在線上環(huán)境,就是這個(gè)道理。

做為一個(gè)老程序員來(lái)說(shuō),對(duì)于線上有哪幾臺(tái)服務(wù)器,IP是多少,內(nèi)存是多大,硬盤(pán)是多大,CPU是幾核的,常用負(fù)載是多少,IO有多少,每天增長(zhǎng)的日志是多少,DB里的數(shù)據(jù)庫(kù)大小是多大,每天的增量是多少,系統(tǒng)中最慢的請(qǐng)求是什么,每天會(huì)訪問(wèn)多少次,最快的請(qǐng)求是什么,每天應(yīng)該訪問(wèn)多少次,每次訪問(wèn)的時(shí)候正常應(yīng)該是在多少M(fèi)S內(nèi)返回,一次會(huì)取多少條數(shù)據(jù),分解到哪幾個(gè)Service,每個(gè)Service的不同時(shí)間請(qǐng)求是多少,有多少穿透DB的次數(shù)。

所有的這些數(shù)據(jù)都要了如指掌,這樣才能夠非常快的定位線上的問(wèn)題。

我們不能說(shuō)這樣的程序員是一個(gè)水平多厲害的高手,但是他如果做到了這么一點(diǎn),他就是一個(gè)久經(jīng)沙場(chǎng)的老兵,這樣才像是一個(gè)職業(yè)的工程師。

? 所以這篇文章的重點(diǎn)就在于是,簡(jiǎn)單的講解一下時(shí)間之箭的運(yùn)轉(zhuǎn),中間會(huì)有哪些環(huán)節(jié),每個(gè)環(huán)節(jié)應(yīng)該耗費(fèi)多長(zhǎng)時(shí)間。

? 簡(jiǎn)單說(shuō),只有先找到妹子,才會(huì)知道應(yīng)該在妹子身上花多少時(shí)間,對(duì)吧?


今天的分享就到這里啦,歡迎大家點(diǎn)贊、轉(zhuǎn)發(fā)、留言、拍磚~

????????技能樹(shù).IT修真院

????????“我們相信人人都可以成為一個(gè)工程師,現(xiàn)在開(kāi)始,找個(gè)師兄,帶你入門(mén),掌控自己學(xué)習(xí)的節(jié)奏,學(xué)習(xí)的路上不再迷茫”。

????????這里是技能樹(shù).IT修真院,成千上萬(wàn)的師兄在這里找到了自己的學(xué)習(xí)路線,學(xué)習(xí)透明化,成長(zhǎng)可見(jiàn)化,師兄1對(duì)1免費(fèi)指導(dǎo)。快來(lái)與我一起學(xué)習(xí)吧~

我的邀請(qǐng)碼:17742750,或者你可以直接點(diǎn)擊此鏈接:http://www.jnshu.com/login/1/17742750

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容