適用讀者:3年如下的後端開發者前端
文章目錄:
1.爲何要作性能優化
2.性能優化以前,先定位問題
3.Nginx和Tomcat
4.Controller和Service又作了什麼
5.Memcache和DB作了什麼
6.據說他們久經沙場nginx
一 爲何要作性能優化程序員
「這破網站慢死了。」果凍咬着牙說,「這些程序員都是幹嗎吃的 ?」
毛毛看着果凍笑,沒說話,畢竟果凍說的破網站是「修真院本身的官網」,畢竟果凍說的這些「幹嗎吃的」程序員就在他們UE組對面。果凍是一個萌妹子,怎麼說都行,毛毛作爲一個PM,但是常常注意培宇桌子下面常備兩塊板磚的。數據庫
培宇有一點點臉紅,果凍對培宇是一直有偏見的,畢竟當衆表白被拒是誰都難以接受的。自那之後,本着「沒有打擊培宇的機會,就創造打擊培宇的機會」的原則,果凍讓培宇生生見識到了什麼叫作「由愛生恨兩重天」。後端
旁邊的小馬哥不幹了,當場就「哐「的一下拍桌子,整個二樓的人都嚇了一跳,看着小馬哥。
果凍也同樣嚇了一跳,回過神來以後就當場發飈了:」偉江你要死嗎?「跨域
偉江原本想說」你行你上啊「,可是看了看果凍漸漸變冷的眼神,終究仍是說不出口,但是氣氛一度很尬啊,只好小聲說了一句:」我去找老大解決去。。。。。。「緩存
全部人:」。。。。。「
培宇笑的不行:」偉江就該這麼有霸氣,在果凍的淫威下終於爆發了,一怒而起,而後一溜煙的跑去找老大了~「性能優化
二 性能優化以前,先定位問題服務器
說到性能以前,先談量化。網絡
說網站慢,那是普通用戶的說的話。
而對程序員來說,必須是到多少MS。
多少MS纔算慢?一般來講,人的眼睛對於200MS以上的時延是有反應的,因此通常而言,一整個頁面都應該在200MS以內完成。
對於複雜的請求,能夠再稍微慢一點,畢竟你們還能忍,能忍的程度跟網站的價值成正比。反正我看小黃片的時候是挺能忍的~
簡單的用戶我的信息這種請求,應該在50MS左右,List的數據,差很少在100MS左右。這是比較正常的數據。
以上這些全是暗滅大人罵偉江的原話。
」因此你作爲一個程序員,過來跟我說網站慢?你應該直接告訴我說如今哪個請求慢,慢到多少MS,應該達到多少MS。「
暗滅大人一邊狠狠的罵了偉江一頓,一邊繼續在QQ上教小師妹學習:「小師妹啊,我據說最近剛上映了一部電影叫作《人民的名義》,我看了看,感受對於寫代碼頗有幫助啊,強烈推薦給你看,這樣,恰好有人買了兩張電影票給我,我帶你一塊兒去學習一下吧。」
偉江趕忙的拿出手機來,兩張票買後,而後截圖發給老大。
暗滅大人看到截圖,這才滿意,跟小師妹又回了句:「稍等啊,我要開個董事會。」
「拿白板來!」老大說。
首先,果凍朝你設了一箭。你接到了果凍射過來的這支愛之箭,看了看箭上附的小紙條,寫的是什麼內容,按果凍的指示把她想要作的事給作完了,而後把結果又放到小紙條上,再扔回給了果凍,果凍收到箭以後,打開看完。
這是一個完整的Http請求過程。
而後老大在白板上這麼畫了一下。
這表示,對於一個網絡請求來講,第一個層面,你須要知道的時間的損耗能夠分解成三大部分。
第一部分前端的響應,通常包括解析和渲染,這部分的性能跟前端的代碼,前端硬件有關係。
第二部分就是網絡延遲,這部分的代碼正常來說是在8~16MS左右,是的,Http請求就是差很少這個性能,若是是WebSocket幾乎能夠作到零延遲,有暗滅大人當年寫的多人在線掃雷(http://game.ptteng.com 支持多人在線玩掃雷,一我的點錯全部人完蛋的惡趣味)爲證。
第三部分就是服務器端的響應,咱們說的是網站慢,通常而言,也就是主要在這裏,要作性能優化的地方,基本上也是看這裏。
偉江聽的正津津有味,忽然間發現老大已經轉身要走了,趕忙拿出手機來又訂了一個燭光晚餐。
「老大,老大,我怎麼才能知道每一段時間間隔多久呢?在哪能夠看獲得啊?」
「F12,Fiddle都行啊,這種叫端到端的響應時間,服務器端的響應時間啊,要看Nginx的Access.log.」老大滿意的點了點頭:「偉江的學習態度很好嘛,不像培宇,太笨,又不願用心。」
「Access.log裏會記錄服務器端本身的響應時間,這是後端查看性能的重要依據,也是找運維背鍋的必備技能。一旦你發現服務器端的響應時間沒問題,而端到端的響應有問題,那就百分百的是網絡問題了,能夠直接找運維同窗背鍋了。」
「這些是作性能優化以前必需要弄明白的,問題到底出在哪兒呢?不然怎麼作性能優化?因此解決性能的問題,跟你泡妹子是同樣的,要先脫掉妹子的外套,再脫掉外套裏面的上衣,而後。。」
偉江擦了擦口水,說:「老大,若是確實是咱們後端的問題呢,前端響應正常,網絡傳輸也正常,就是後端響應出問題,該怎麼解決?」
三 .Nginx和Tomcat
「爲何要在前端掛一個Nginx,而不是直接用Tomcat呢?」
「你別管,總之好處多多了,不過是域名,仍是跨域,仍是防Ddos攻擊,Nginx都是利器,很好用。如今就照着來。」
Nginx至關因而一個大的總管,全部的請求都是先到Nginx這裏來,而後再發給後面的Tomcat,或者是Resin什麼的。
後面的Tomcat像當因而一個個漂亮女生宿舍的話:
因此Nginx就像當因而女生宿舍的門衛
對的。總之Nginx很贊,我很喜歡。Nginx會記錄有全部的出入時間。
若是Nginx的耗時比較長,通常而言,問題都不太會直接出在nginx身上,能夠直接再去查Tomcat/resin/jetty這些女生宿舍的崗了,哦,不是,去查看這些服務器的日誌響應時間了。
因此,Nginx和Tomcat之間的圖應該是這樣的。
Tomcat自己也會有一個日誌記錄,也是Access.log,其餘的叫別的什麼日誌無所謂了,反正從名字來看,就是進女生宿舍的時間和離開的時間--那羣Tomcat的研發人員必定是作了不少的實地調研纔能有如此神似的命名。
那麼鍋就繼續甩給了Tomcat。Tomcat以後是什麼呢?基本上就所有是Java人員寫的代碼了。因此咱們要不要往女生宿舍裏偷偷看一眼?
「但是最關鍵的就是女生宿舍吧,哪能只偷偷看一眼就走!」偉江有點不滿意。
四 .Controller和Service又作了什麼
說的沒錯,Tomcat裏的時間其實還能夠再分解的更細一些。第一個接受到響應的就是Controller,而以前說過,Controller一般是用來控制Service的,你能夠理解爲,每個Service就是一個漂亮妹子。
Controller就是一個宿舍的宿管員。就是少林足球裏的包租婆,她來負責管理這些小妹妹作什麼事兒。
Controller依次調用女生Service1,女生Service2,女生Service3~而後再把結果返回給你。
因此Tomcat響應的時間能夠分爲:
1.Controller的處理時間
2.Service的調用時間
3.返回結果的處理時間
controller自己的處理事情,通常都會是在開始和結束各打一條毫秒數這是全部的業務邏輯處理的總時間。調用各Service的時間包含網絡傳輸和Service的響應時間。返回結果的時間通常都是解析成Json的時間。
生成Json的時間一般很短,很短,網絡傳輸的時間說很差,RMI的話,除第一次創建鏈接外,幾乎能夠忽略不計,可是一個Controller裏調用上百次的話,速度就會慢起來。Http無疑是最慢的,單純創建就要花幾MS,對性能有更高要求的話,用Thrift和ProtocolBuffer等。
而我通常都喜歡用RMI,不喜歡異構的東西,Http又引入了額外的負擔,因此比較喜歡用Tuscany直接調用RMI。
因此性能優化的重點,就是要弄明白,若是一個大老爺們,好比說培宇,進了女生宿舍以後,總共花了500多MS的時間,他在包租婆那裏花了多長時間?他跑到妹子1的牀前花了多久?和妹子1在一塊兒同幾MS?跑到妹子2的牀前是多久?在妹子2那裏花了幾MS?
這些數據都要清清楚楚,仍是要用圖來代表一下。
這個就是小培宇。若是他爬上每個妹子的牀以後都回來找包租婆登記一下,就是這樣的。
若是他爬了一個妹子的牀,而後趕忙的去爬了另外一個妹子的牀,這就是另外一個服務調用服務的過程了。
這兩種方式的優劣,咱們隨後再說。
若是他進去以後變成了8個小培宇,每一個小培宇分別去上8個妹子的牀,這就是多線程和異步。
若是他本身帶了一個小黑板,啪啪啪寫上本身的地址,而後就走。8個妹子看到地址以後各自去找小培宇,這就是消息隊列。
總之,先不討論這麼複雜的東西,咱們就只說,培宇是一個妹子一個妹子的上。。。。。牀。
那麼,Controller那裏應該怎麼統計時間呢?
通常而言,咱們會手寫一個AOP的Util。並不會在Controller裏手寫StartAt和EndAt。
這個Aop寫起來很容易,正常來說,會在代碼裏這麼寫:
若是超過了50MS,記錄日誌,入參,時間。
若是不超過50MS,不記錄。
這個50MS依據每一個人的身體狀況,哦不,依據每一個應用的狀況來自行設置。
因此,到了這裏,你就會知道了,咱們把果凍射來的愛之箭,已經穿透了包租婆,到了女生宿舍,而且分解到了每個牀位的時間。
這就是一個分析和定位的過程,而一般就是在Controller的代碼裏,通常咱們都叫作WEB工程,在這裏去用Aop來記錄第一個Service的響應時間。
若是咱們發現了,培宇在2號女生那兒花費的時間特別長呢?
五.Memcache和DB作了什麼
「那就把培宇閹了!」偉江斬釘截鐵的說。
「好的,如今就動手。」 老大滿懷期待的看着他。
這得把培宇喊過來,問問他在2號女生那裏作什麼了。
寫到這裏我必須得說,這是公開版,公開版只能說,培宇在約2號女生看電影。
內部版,非公開發生的,培宇作的事情就比較多了。。
好了,先說看電影。
培宇說:乖,咱們去看電影吧。
妹子說:好的,我要找找個人身份證。
這個時間發現身份證不在身邊,在老家,因而妹子說,乖,你等着,我去老家把身份證拿過來。
這就叫作直接從DB裏拿數據。
因此時間性能的損耗,就在因而:培宇和妹子說話,妹子回老家拿身份證。
大概的場景就是這樣的。
培宇說:乖,咱們看電影去吧。
妹子說:好啊,好啊,等我,我回老家拿身份證,而後一個月過去了。
培宇和妹子想了想,仍是沒辦法看電影。
第二次培宇又說:乖,咱們看電影吧。
妹子說;好啊,好啊,等我,我回家拿身份證,而後一個月又過去了。
培宇和妹子再見面以後,想了想,仍是沒辦法看電影。
上一篇講過Dao。其實Service裏對於Dao的訪問時間分析,也是這麼記錄的。同理,若是你要用到多個Dao,多是先回老家拿身份證,再去商場買件衣服等等等等。
而咱們統計妹子去拿身份證的時間,也是同理能夠用剛剛說過的Aop的性能統計Util.
這樣一個Service處理事情的時間,就分紅了本地運算和獲取數據的時間。
一般本地運算的時間會比較快,而獲取數據的時間會比較慢。
若是說你發現了妹子老是回老家,並且時間恰好是一個月,你怎麼辦?
給妹子提個醒,可不能夠把身份證放到旁邊的衣櫃裏?這樣咱們就能夠直接從衣櫃裏拿身份證了啊。
這個衣櫃,就叫作緩存。
而通常而言,咱們的包租婆是無論妹子從哪拿身份證的,總之能接待好客人,呃,接待好培宇就好了。
因此若是要繼續區分,性能問題。必需要知道,數據有沒有走緩存?從緩存中的數據取出來要多久?正常狀況下應該幾MS,爲何妹子花了20多MS?是否是櫃子前面的人比較多?仍是從牀到櫃子中間的路壞了?櫃子是在哪裏放着的?
妹子回老家取身份證,會不會堵車?
這些都是須要靠日誌來記錄時間,也簡單提醒一下,假設不是培宇一我的來呢。10000我的同時來呢?你必須得在日誌裏記錄一些關鍵信息,確保知道哪一個時間是哪一個老闆,呃,哪一個客戶的。
六.據說他們久經沙場
其實性能優化有不少不少方案,不一樣的應用場景,解決方案是不一樣的。可是最根本的就是要明白,時間倒底損耗在什麼地方?
對於果凍來講,就是簡單的射了一支愛之箭,後面作了哪些,是不須要知道的。
但是偉江就必須得明白,培宇對每個女生宿舍的妹子都作了什麼。在保安那裏花了多久,在包租婆那裏花了多久,在每個女生牀上花了多久,妹子從櫃子裏取身份證要多久,從老家取身份證又要多久。
咱們一直說的,一個程序員的真正工做的地方不在筆記本上,也不是在開發環境,也不是在測試環境,而是在線上環境,就是這個道理。
作爲一個老程序員來講,對於線上有哪幾臺服務器,IP是多少,內存是多大,硬盤是多大,CPU是幾核的,經常使用負載是多少,IO有多少,天天增加的日誌是多少,DB裏的數據庫大小是多大,天天的增量是多少,系統中最慢的請求是什麼,天天會訪問多少次,最快的請求是什麼,天天應該訪問多少次,每次訪問的時候正常應該是在多少MS內返回,一次會取多少條數據,分解到哪幾個Service,每一個Service的不一樣時間請求是多少,有多少穿透DB的次數。
全部的這些數據都要了如指掌,這樣纔可以很是快的定位線上的問題。
咱們不能說這樣的程序員是一個水平多厲害的高手,可是他若是作到了這麼一點,他就是一個久經沙場的老兵,這樣纔像是一個職業的工程師。
因此這篇文章的重點就在因而,簡單的講解一下時間之箭的運轉,中間會有哪些環節,每一個環節應該耗費多長時間。
簡單說,只有先找到妹子,纔會知道應該在妹子身上花多少時間,對吧?
======廣告時間======
------------------------------------------------------------------------------------------------------------------------
「咱們相信人人均可以成爲一個工程師,如今開始,找個師兄,帶你入門,學習的路上再也不迷茫。
這裏是技能樹.IT修真院:http://www.jnshu.com,初學者轉行到互聯網行業的彙集地。"
歡迎加IT交流羣565734203與你們一塊兒討論交流