最近最佳化了一項系統的效能,總結心得如下,希望對大家有用。先說大致的業務以及最佳化的成果(這不是炫耀,但是此處應該有掌聲。哎,自娛自樂是種病,都怪我放棄了治療)。
同時處理N個使用者,每個使用者需要根據不同的條件進行相應的操作,這裡的操作可能是更新其他表,可能是插入其他表得根據使用者的狀態進行判斷。當然了這裡的N不是全部的使用者,是根據聯集查詢得來的一個List。需要說明的是這個查詢語句已經被前人最佳化的非常好了,所以查詢的最佳化不是考慮範圍之內的。
說到效能最佳化,準確的說是底層效能最佳化說到底無非就是JPQL改SQL或者無索引加索引這些簡單的操作。只要找到了原因在哪,修改代碼絕對不是問題,就像那首歌裡唱的“有一位老人在中國的南海邊畫了一個圈”畫完圈之後要做的事情是容易的,難的是在哪裡畫這個圈。同樣畫圈的故事還有下面這個:
美國福特公司一台大型電機發生故障,所有工程師束手無策,最後請來一名德國工程師。他繞著電機走了幾圈,聽了聽聲音,然後用粉筆在電機上畫了一個圈,對所有人說,“開啟,把這裡的線圈減少16圈”。結果,故障排除了。事後,德國工程師索要3萬美元報酬。福特公司提出疑問,為什麼畫一個圈居然索價這麼高?德國工程師回答,畫一個圈1美元,知道在哪裡畫圈29999美元。
如何發現效能瓶頸
第一:測試資料儘可能真實
第二:測試資料儘可能真實
第三:參考上面兩點
為什麼這麼說呢,這次最佳化的時候因為資料量是一千五百萬,考慮到時間問題自己當時就想偷個懶,造幾百萬資料得了,結果運行了幾遍沒發現什麼問題。至於偷懶的原因我是這麼安慰自己的“就算用預存程序對資料庫進行插入操作,幾百萬條資料也是需要不少時間的,而且資料基本上用完還得再造(好吧我承認我的水平窪,請大牛們賜教如何快速造資料啊)”種種原因吧,兩天之後還是一籌莫展,於是就像普通的偵探小說中描述的那樣,在到期日之前“案例”一度陷入僵局,最後被逼無奈才開始使用生產資料進行測試。
不要忽略任何線索
起初第一次用生產資料測試的時候只是關注後台日誌中的錯誤,壓根就沒有把什麼warning放在眼裡更別說什麼info了(事實證明info的確沒什麼大用)後來查看日誌的時候發現了warning的日誌,原來串連池滿了。Glassfish預設是32,改成320之後運行穩定,並且總時間從五十多分鐘提升到了六分鐘。其實我知道這個數字是需要一步一步調整的,指導調整到一個最佳的數值,既不浪費記憶體又能保證系統效率。效能最佳化說難也難說簡單也簡單,簡單到比之前就多畫了一個圈,難在解決問題之前你不知道問題到底出在哪裡。
(借我借我一雙慧眼吧$_$)
托爾斯泰說“幸福的家庭是相似的,不幸的家庭各有各的不同”對於系統也是一樣的,“高效能的系統是相似的,低效能的系統各有各的瓶頸”。這次的調優僅僅是系統最佳化技巧的冰山一角,但是調優的思路是通用的,找出瓶頸----解決瓶頸,所以說找問題的能力比解決問題的能力更難能可貴。