軟體品質指標系列(三):軟體品質如何測量
在這一系列的第一回我們談到,我們是軟體工程師,不談虛幻的概念,只講能夠量化追蹤的數值指標,那麼,
我們要怎麼把品質轉換程數值指標呢?
軟體品質如何測量
===============================================================================
幾個故事
-------------------------------------------------------------------------------
在開始講怎麼做前,我想先講兩個我親身的經驗,在我第一份工作時,前雇主是做手機遊戲的,整間公
司有兩百個員工,但是只有三個是做Server端的,在 2005 年時,多數遊戲都是單機板的,那時公司
簽下 World Series Of Poker 要做多人的線上遊戲,需要開發一個簡易的配對及遊戲訊息交換的伺
服器,當然,大家當年都沒有經驗,所以說,要怎麼樣確保在上線時,不會被用戶衝垮就變成我的工作。
而在我第二份工作時,也有相似的經驗,我們本來已有一個運作中的音樂平台,讓公司內外超過40個Partner使用;
當時,公司又簽下一個合約,說是在三個月後的 6/1 ,會新增 200萬用戶!如何不讓大水衝垮我們的
應用程式,又變成我那幾個月的工作重點。
.. image:: /images/2012-05-23/troops.jpg
:width: 800 px
Load Test
===============================================================================
寫到這邊,大部份的讀者應該都知道接下來要講的是 Load Test 了,Load Test是個很大的議題,通
常我們在講 Load Test 時,常講的其實是三件不同的事
- Performance Test
- Stress Test
- Longevity Test
這三個測試,用的工具雖然一樣,但是要找個指標跟目的卻是大不相同。
Performance Test
-------------------------------------------------------------------------------
Performance Test 的目地是在找出應用程式的 baseline performance ,做為未來績效評估及設計變
革時的依據。
被 Performance Test 的標的物,通常是已經 feature complete 的模組,然後我們將對模組的每
一個功能,一個一個進行黑箱及白箱測試;然後再用腳本的型態,模擬實際上線的流量,再來測試看看
各功能間對效能的互相影響程度;最後,是找到測試標的物的 Turning Point 及 Scale Factor。
尋找 Best Case Performance
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
尋找應用程式的 best case performance 大概是最常被忽略的事了, best case performance 指的是你
一個功能的最佳效率,不管怎樣測試,對單一功能來說,怎麼樣你的效率都不可能會再比這個數字
好了;這個數字的第一個用處就在這,如果你的最佳效率比目標效率還糟,剩下來的就不用測了,
因為怎樣都會比這個數字還糟,只能先停下來,回去修改程式碼增進效能。
Best Case Performance 的測法是:
1. 將應用程式啟動
2. 先用幾個 request 替應用程式暖身(warm up),以 Java VM 來說,這樣可以讓 Hotspot VM 幫 bytecode 最
佳化,有些需要被啟動的內部原件也會被啟動。
3. 接著是一個一個的慢慢送一百個 requests ,然後取平均值及標準差。
若是標準差的值過高,或者是反應時間有增長的現像,那麼這個狀況應該記錄下來,然後使用白箱
測試的工具(如 `yourkit profiler`_ 去找問題的根源。
除了平均數及標準差外,常用的數字還有
- mean
- standard deviation
- minimum
- maximum
- 96 percentile
- 99 percentile
- 99.9 percentile
- 5 minutes moving average
- throughput
- error rate
另外,圖表也是常用的工具,因為相較於數字,圖表更容易看出來趨勢的走向;以下圖為例,藍線的
平均反應時間是1.354秒,但跑load test二十分鐘後,每一個 request 都已經超過了平均數,因
此將數字用圖像來呈現是有助於判別數字的。
.. image:: /images/2012-05-23/chart-1.png
:width: 480 px
.. _yourkit profiler: http://www.yourkit.com/
建立 Performance Baseline
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
接下來的工作,是定出比較的基礎,建立一個你覺得合理的流量,然後就這個比較基礎去找出來不同
狀況下的平均反應時間及處理量的變化。
基礎效能的建立,我們要先控制兩個變數 **requests per minutes** 及 **number of concurrent requests** ;
透過調整這兩個變數,先找出反應時間較 best case 的流量,然後就此數字開始調整到一個你覺
得合理的值,開始進行 Load Test。
劉接下來我們開始把 **requests per minutes(RPM) 倍增** 但 **number of concurrent requests(CR) 不變** 來看,當流量
增加時應用程式的反應時間會如何增長,接著是 RPM 及 CR 同時都倍增,看反應時間如何增長,
依此規則,就二的次方(2^N)開始往上增加,直到 response 開始嚴重衰退,或者 throughput 開
始衰退。
接著,如果你的應用程式支援 Scale-Out ,那麼,我們依此規則,就 RPM, CR, Machines 三
個變數再次就二的次方(2^N)開始調整流量來做測試。
前面這個過程,可以幫我們了解以下幾件事
- 應用程式對壓力的反應是如何,當流量被增時,反應時間成長的幅度是線性還是成等比級數成長。
- 處理量 throughput 是否會隨著 request 數增加而增加,是否在超過某個轉折點時,會開始
反轉下降
- 上述的轉折點,便可當做未來評估是否需要增加機器或者是昇級機器的基準值。當實既須求接近這
個點,或有事件會造成流量超過這個點,那麼,我們就可以在事前進行反應。或者,在監控應用程
式中加入警告,當線上程式逼近這個值的時候,主動告知我們該加機器了
- 當我們增加機器時,如果應用程式不是寫成完全 stateless 的,而是有共享資料資源時,那麼
,scale factor便會小於 2,那麼,我們需要關查 scale factor 到底是隨著機器的增加而
不變、還是緩慢成長、或者是快速成長。即使因為某些因素讓我們不能夠準備有實際上線時的機器
數,但是透過分析 scale factor ,我們可以預估上線該使用多少機器。
Stress Test
-------------------------------------------------------------------------------
與 Performance Test 不同的是, Stress Test 是看,應用程式在極度的狀況下,是怎麼樣反
應的,是全面性的停止服務,還是仍能正常處理部份的 request ,其餘未能處理的部份是被堆到排
程中等待處理、還是直接收到錯誤訊息告知服務暫時不可用。而當這極端的狀況停下來後,應用程式
是否會自行回復正常,還是需要
重新啟動才能回復正常。
Stress Test 的方式是直接把 performance test 中 **處理量** 開始反轉的那個點的流量再
次倍增,看處理量及反應時間會如何的變化。
Longevity Test
-------------------------------------------------------------------------------
Longevity Test 跟前述兩者不同的是, Longevity Test 是在看,應用程式對長時間、持續性、
平緩的流量是如何反應的,是否在某個時間點會有不良的反應,或者是說會有處理量越來越少或反應時
間越來越長的跡象。
透過 Longevity Test 我們可以發覺
- 應用服務是否有 memory leak
- 是否有背景的排程工作,造成某個時間點系統資源會被大量耗用
Monitoring
===============================================================================
除了從應用程式的外部去觀查應用程式的執行效能,我們還可以更進一步的
- 從作業系統了解CPU, Memory, Disc I/O, and Network Usage
- 從JVM 了解 Memory Usage, Object counts, GC Cycles.
- 從應用程式自訂的 metrics 來觀察 request count, method call time, size of queue,
cache hit/miss ratio, etc...
透過截取、記錄、追縱這些數據,搭配上 Performance Test 產生的圖表,我們可以再進一步的了解
應用程式耗用了多少的資源,應用程式的 bottleneck 在那,是 cpu bound, memory bound,
disc io bound or network bound.
.. note::
不要小看了這些監控的細節,我的某個程式,有少量用到 ActiveMQ, ZooKeeper 做溝通,照理說
應該是 cpu or memory bound的應用,但是經過幾次 load test ,發覺不管加多少機器,總處
理量還是不變。後來翻了翻OS來的數據才發現,整個環境的網路頻寬被限制在 250M bps ,再進一
步了解到原來 Amazon EC2 的 Load Balancer 把流量限制在這個數字。
監控的工具有很多種,不過脫不了兩大類
- **監控系統用量** 如: Munin, Graphite, RRDTools
- **監控系統異常** 如: Nagios
這些監控工具,我們不只是可以套用在 Load Test 時使用,更該被大量的佈建在監控線上的應用程
式及外部的服務上,透過長期的追縱,我們可以了解到應用程式及外部的服務的可用度及可靠度。
(全文完)
===============================================================================