如何進行系統優化

maqianmaqian發表於2010-11-05

前兩天跟同事討論,說到高併發系統如何做優化,提到這個問題,他說他有些茫然,有點不知道該如何下手。
我想了想這幾年做的各種系統優化工作,正好也簡單總結一下,總結起來就是:一個核心,N種手段。
一個核心就是:多、快、準。
N種手段就要圍繞上面的核心做的各種處理。

上面這個核心字多點說也就是:更多使用者訪問、更短響應時間、資料正確性。
優化的過程,我的想法就是先順藤摸瓜,沿著一個請求發生的路徑一路看過去,測量一下每個點上消耗的時間,會發現很多消耗時間多的點,都是值得你去優化的地方。然後再考慮在每個點上發生了擁擠導致響應時間變長了又該怎麼解決。
當然也不需要一上來就全面優化,連影響最小的地方也不放過。先優化對你的效能影響最大的地方,效果是最好的,解決主要矛盾才是關鍵。不同的情況下,會有不同的優化方式。

簡單地來看一個瀏覽器使用者訪問的流程:
瀏覽器->伺服器->返回結果顯示
這麼簡單地看,可能想得到的優化手段很少,常見的可能就是優化sql,加快資料庫處理;加個快取,加快返回;使用靜態檔案,減少動態計算。

細分開來看每一個步驟:
1 瀏覽器發起一個請求,如果本地有快取會請求本地快取檔案,沒有快取會請求伺服器。所以這裡就有一個優化點:需要把常用的css和js檔案獨立成獨立的靜態檔案,一次載入以後,後面直接載入本地快取。另外IE瀏覽器核心在請求圖片下載時會限制一次只能同時從同一個域名下載兩個檔案,這裡又有優化點,分散圖片儲存的域名。使用靜態檔案,減少計算的同時增加本地快取的使用,減少請求。靜態化是常見的一種優化手段。

2 瀏覽器真實發起請求伺服器時,首先被請求到的是伺服器的作業系統層,那麼伺服器的作業系統對外界連線的響應能力,就是你需要了解的東西了。比如linux的核心引數的調整如何影響最大連線數,簡單的一個例子就是在一個預設最大檔案控制程式碼數只有1024的伺服器上,超過這個壓力的時候,你如何優化你的程式,也都沒有意義。入口只有那麼窄,你得把口給擴開。熟悉伺服器的效能,調優系統核心也是一個必要的手段。

3 系統層再把連線交給你的server做處理的時候,server的配置這個時候也相當重要。比如apache的最大連線數,tomcat的最大連線數。對server的配置調優很影響效能。比如tomcat在處理靜態檔案上的能力比apache要差很多,所以在apache+tomcat的負載均衡就能很好地進行動靜請求的分離,提高響應速度。又比如tomcat新版本里的NIO技術又比普通IO效能好上不少。對server的瞭解,要保持跟蹤最新動態。

4 server再把資料交給你的程式處理的時候,就到了考驗你程式設計能力的時候了。你得對你的程式的執行效率非常清楚。必須保證每個響應都在儘量短的時間內執行成功。還有比較常見的一些對不常更新的資料使用記憶體快取來加快訪問。記憶體永遠是最快的。這方面的優化也有非常非常多的事情可以去做,而且跟你的程式設計息息相關。

5 程式處理的時候,資料庫連線池的使用,連線池大小的配置,連線池效能的優化,sql語句的優化,等等都可能影響你的程式的效率,這些地方永遠是值得關注的。當然,優秀的演算法在這個地方是少不了的。一個好的業務邏輯設計,可能極大提升你的程式效能。對資料庫操作的調優也是一個永遠的話題。

6 資料傳遞到資料庫進行儲存和查詢的時候,你就必須對你的資料庫的使用有所瞭解,知道資料庫本身的哪些配置可以優化從而帶來效能的提升。一個簡單的例子就是在記憶體足夠大的時候,增大mysql的記憶體快取就可以極大提升它的響應速度。

7 現在server把資料返回給使用者了,那麼返回的資料的大小又同樣影響著結果的顯示速度。儘量減小資料的大小,比如開啟apache的gzip就能極大壓縮常見的靜態檔案,可以保證使用者更快完出資料的下載,同時節省你的伺服器使用頻寬,老闆一定會很高興的。

8 使用者下次訪問的時候,同樣面臨一個優化的方式:是利用上次跟伺服器建立好的連線再次通訊呢?還是重現跟伺服器建立連線?這就是在server端做配置要考慮的一個問題,在低併發下,保持跟使用者建立的socket連線,並且讓使用者通過這個連線來多次訪問,可以提高速度。但是在高併發下,大量這種建立好的連線就意味著其他使用者失去了進來的機會。所以這個是需要權衡的。一般情況下最好可以預估一下一個使用者可能在多長的時間裡連續發起多少個請求,然後可以把使用者斷開,把資源用來服務其他使用者。

9 ajax技術也是在減少大請求,使用更小的區域性資料更新來代替整個頁面的重新整理,加快使用者的響應速度,結合靜態化能完美改善效能。

這是對一個使用者的訪問的時候的考慮,然後就要考慮多使用者情況的問題(有些是上面提到過的):
1 作業系統對多使用者訪問時的一些限制的優化
2 server的併發量的優化
3 多使用者併發下,更多地要仔細考慮程式在資料操作的併發上的問題。比如物件的鎖,資料庫的鎖,事務,等待處理的資料的排隊方式等等。你需要知道讀寫分離的好處,應該隔離不同操作間的等待。另外併發帶來的鎖等待問題需要極大地關注,往往不是在記憶體就是在資料庫裡,發生著大量併發鎖等待,導致你的程式緩慢。
4 對資料庫的鎖的機制必須深入瞭解,比如mysql不同引擎的帶來的鎖表和行級鎖對效能的影響。同時要在自己的邏輯處理上要控制好不同使用者同時操作的問題,時刻要繃緊這個弦。多資料叢集,讀寫分離等等機制也是需要深入瞭解的。

以上是我一些簡單的零碎總結,並不全面,也不細緻,主要想表達一個思考的過程。不在於你都學會了什麼,發現問題,研究問題,解決問題的能力,才是最重要的。
其實每一個點上,基本上你都可以找到N多牛人寫的很牛很細緻的書來講具體怎麼優化的,需要的時候可以好好去找書來研究一下。
深入去了解每一個點上的優化,你會發現,網際網路的魅力真的是奇妙無窮!

相關文章