獨秀天狼-職場雜談 爲什麼要做性能調優

開場白

大家好,我有一個朋友,有一次他跟我說,他們公司的系統從來沒有經過性能調優,功能測試完成後就上線了,線上也沒有出現過什麼性能問題呀,那爲什麼很多系統都要去做性能調優呢? 當時我就回答了他一句,如果你們公司做的是大型的互聯網網站,不做系統性能優化就上線,試試看會是什麼情況。如果是你,你會怎麼回答呢?今天,我們就從這個話題聊起,只要大量用戶參與的系統,我們必然要做性能優化。當然要做好我們還有很長的路要走,希望能跟你一起弄明白這幾個問題:我們爲什麼要做性能調優?什麼時候開始做?做性能調優是不是有標準可參考?

爲什麼要做性能調優

一款線上產品如果沒有經過性能測試,那它就好比是一顆定時炸彈,你不知道它什麼時候會出現問題,你也不清楚它能承受的極限在哪兒。

有些性能問題是時間累積慢慢產生的,到了一定時間自然就爆炸了;而更多的性能問題是由訪問量的波動導致的,例如,搞個活動或者公司產品用戶量突然上升;當然也有可能是一款產品上線後就半死不活,一直沒有大訪問量,所以還沒有引發這顆定時炸彈。 現在假設你的系統要做一次活動,產品經理或者老闆告訴你預計有幾十萬的用戶訪問量,詢問系統能否承受得住這次活動的壓力。如果你不清楚自己系統的性能情況,也只能戰戰兢兢地回答老闆,有可能大概沒問題吧。 所以,要不要做性能調優,這個問題其實很好回答。所有的系統在開發完之後,多多少少都會有性能問題,我們首先要做的就是想辦法把問題暴露出來,例如進行壓力測試、模擬可能的操作場景等等,再通過性能調優去解決這些問題。 系統響應就是體現系統性能最直接的一個參考因素。 那如果系統在線上沒有出現響應問題,我們是不是就不用去做性能優化了呢?講個真實的故事。 曾經我的前前東家系統研發部門來了一位大神,爲什麼叫他大神,因爲在他來公司的一年時間裏,他只做了一件事情,就是把服務器的數量縮減到了原來的一半,系統的性能指標,反而還提升了。 好的系統性能調優不僅僅可以提高系統的性能,還能爲公司節省資源。這也是我們做性能調優的最直接的目的。

什麼時候開始介入調優

解決了爲什麼要做性能優化的問題,那麼新的問題就來了:如果需要對系統做一次全面的性能監測和優化,我們從什麼時候開始介入性能調優呢?是不是越早介入越好? 其實,在項目開發的初期,我們沒有必要過於在意性能優化,這樣反而會讓我們疲於性能優化,不僅不會給系統性能帶來提升,還會影響到開發進度,甚至獲得相反的效果,給系統帶來新的問題。 我們只需要在代碼層面保證有效的編碼,比如,多注意編碼規範,可以參考阿里的開發規範來約束我們開發,減少磁盤 I/O 操作、降低競爭鎖的使用,以及使用高效的算法等等。遇到比較複雜的業務,我們可以充分利用設計模式來優化業務代碼。例如,發送各種郵件,短信,微信,釘釘,我們可以用裝飾模式和策略模式去設計這個業務。 在系統編碼完成之後,我們就可以對系統進行性能測試了。這時候,我們在提供的參考平臺上進行壓測,通過性能分析、統計工具來統計各項性能指標,看是否在預期範圍之內。 在項目成功上線後,我們還需要根據線上的實際情況,依照日誌監控以及性能統計日誌,來觀測系統性能問題,一旦發現問題,就要對日誌進行分析並及時修復問題。

總結
  1. 前期不用考慮性能優化
  2. 多做一些編碼級別的優化
  3. 使用阿里規範來約束自己團隊整體的開發水平
  4. 複雜的業務多用設計模式來設計開發,比如單例設計模式,策略設計模式,觀察者模式。
  5. 做好日誌的監控(可以在架構設計的時候,記錄每個調用的追蹤id,這樣可以有利於排查)
  6. 做好各種異常的處理

有哪些參考因素可以體現系統的性能

在這裏我已經介紹了項目研發的各個階段性能調優是如何介入的,多次講到了性能指標,那麼性能指標到底有哪些呢? 在我們瞭解性能指標之前,我們先來了解下哪些計算機資源會成爲系統的性能瓶頸。

木桶原理
木桶定律是講一隻水桶能裝多少水取決於它最短的那塊木板 。一隻木桶想盛滿水,必須每塊木板都一樣平齊且無破損,如果這隻桶的木板中有一塊不齊或者某塊木板下面有破洞,這隻桶就無法盛滿水。

我們把系統的整體性能比作是一個大的木桶那麼他的組成部分就是:

整體的系統性能要依靠 CPU,內存,磁盤IO,網絡,異常,數據庫,鎖競爭(線程上下文切換)

CPU:有的應用需要大量計算,他們會長時間、不間斷地佔用 CPU 資源,導致其他資源無法爭奪到 CPU 而響應緩慢,從而帶來系統性能問題。例如,代碼遞歸導致的無限循環,正則表達式引起的回溯,JVM 頻繁的 FULL GC,以及多線程編程造成的大量上下文切換等,這些都有可能導致 CPU 資源繁忙。
內存:Java 程序一般通過 JVM 對內存進行分配管理,主要是用 JVM 中的堆內存來存儲 Java 創建的對象。系統堆內存的讀寫速度非常快,所以基本不存在讀寫性能瓶頸。但是由於內存成本要比磁盤高,相比磁盤,內存的存儲空間又非常有限。所以當內存空間被佔滿,對象無法回收時,就會導致內存溢出、內存泄露等問題。
磁盤 I/O:磁盤相比內存來說,存儲空間要大很多,但磁盤 I/O 讀寫的速度要比內存慢,雖然目前引入的 SSD 固態硬盤已經有所優化,但仍然無法與內存的讀寫速度相提並論。
網絡:網絡對於系統性能來說,也起着至關重要的作用。如果你購買過雲服務,一定經歷過,選擇網絡帶寬大小這一環節。帶寬過低的話,對於傳輸數據比較大,或者是併發量比較大的系統,網絡就很容易成爲性能瓶頸。
異常:Java 應用中,拋出異常需要構建異常棧,對異常進行捕獲和處理,這個過程非常消耗系統性能。如果在高併發的情況下引發異常,持續地進行異常處理,那麼系統的性能就會明顯地受到影響。
數據庫:大部分系統都會用到數據庫,而數據庫的操作往往是涉及到磁盤 I/O 的讀寫。大量的數據庫讀寫操作,會導致磁盤 I/O 性能瓶頸,進而導致數據庫操作的延遲性。對於有大量數據庫讀寫操作的系統來說,數據庫的性能優化是整個系統的核心。
鎖競爭:在併發編程中,我們經常會需要多個線程,共享讀寫操作同一個資源,這個時候爲了保持數據的原子性(即保證這個共享資源在一個線程寫的時候,不被另一個線程修改),我們就會用到鎖。鎖的使用可能會帶來上下文切換,從而給系統帶來性能開銷。
回顧我自己的項目經驗,有電商系統、支付系統,智能家居系統。系統每天都要承受各種大量的訪問壓力,所以我對系統的性能要求非常苛刻。除了通過觀察以上指標來確定系統性能的好壞,還需要在更新迭代中,充分保障系統的穩定性。 這裏,給你延伸一個方法,就是將迭代之前版本的系統性能指標作爲參考標準,通過自動化性能測試,校驗迭代發版之後的系統性能是否出現異常,這裏就不僅僅是比較吞吐量、響應時間、負載能力等直接指標了,還需要比較系統資源的 CPU 佔用率、內存使用率、磁盤 I/O、網絡 I/O 等幾項間接指標的變化。
在這裏給大家留一個思考題?

除了以上我給出的性能指標你是否還有其他的參考方式?歡迎給我留言。

本文中版權歸獨秀天狼團隊所有,轉載請標註清楚。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章