標籤: Availibility

壓力測試到底在關注什麼?

壓力測試到底在關注什麼?

最近請同事開始使用工具做壓力測試,一開始講目的是為了”知道”我們的API能否承受一定的使用者使用我們的系統,至於多少使用者呢?假定是1000個線上用戶為目標。但過了一陣子,發現大家似乎 對於要測什麼,怎麼測,測完後的行動,壓力測試跟效能測試差異,都還有一些疑慮。導致無法有效的進行。

先講”相對”最簡單的議題,怎麼測,首先應該是依賴工具,有各種技術方案,有的用JMeter,有的用Script的Tool例如K6。端看想要如何測試往下延續或保持這種壓測的節奏。

JMeter的考量可能是有GUI的壓測劇情設定編排的畫面,對於比較不寫程式的,也有機會去達成壓測的工作。一樣可以做到算是API間的相依,像是從Login拿Token,再拿Token去打 其他API做驗證後的邏輯。這些都做的到,報表也有整合好可以看到一些圖表數據。這些數據我就先不討論了,都是有定義的。

其他工具例如K6,就可以讓你用JavaScript的方式寫腳本,方便用程式的方式 自動化 的,重覆使用化的去設計你的壓測流程,這是好處,不過就會有一點點門檻。(這對程式有點基礎的就學習上相對簡易很多)

再來一層就是我們要討論 為什麼要壓力測試,壓力測試的對象從不同的面象又可以做一個粗淺的分類,例如:

  1. front-end 或是 back-end
  2. 元件或是 end 2 end 測試
  3. 單一協定架構或混合架構。

上述分類不代表什麼,只是說明你可能可以整體來看你測試對象的分類為何 ,因為能錨定你的對象跟你選擇的工具,腳本的寫法都有些關係。不過我認為,這些還是可以概念上分成由上而下拆解,還是由下而上堆疊來驗證。

由上而下,不外乎還是把你的測試對象視為一個黑盒子。可能你知道中間的構成是什麼,也可能不知道或不確定,因此透過 測試,可以幫助你推論 瓶頸在何處,但都要數據來證明。愈複雜的組成有可能有愈多的依賴。因此你一開始愈來,拆的成本就愈高。

由下而上,我認為是你可以透過很多碎片/單元化的可驗證組件逐一測試。這些分開的成本也不小。疊到符合”使用場景”要花的時間,是你需要考慮的。例如假如知道一隻極度單純的API查詢 資料庫1次的數據(先知道環境依賴的跟與業務邏輯無關的部分),其實你可以往下驗證到,例如你的登入,背後可能是1隻API結合查詢 3次 ,寫入1次 ,這樣的子的邏輯複雜度。在你設定的壓力狀況下的成績如何。再來逐步的疊加可能登入Api+查詢Api複合性的商業邏輯,不過注意必須合理,若網站所有Api不考慮相關性,相依性 平均的去壓測他們,這樣的測試也是既耗時也浪費的。

因此從上述的方向,並不是說你只能走一個方向,而是你要怎麼透過”不同的角度”去找答案!

以API的部分,舉個例子:

一開始 可能設想由上而下,我們現在電商網站最常被使用是登入嗎?可能不是,大家要嘛就已經登入了,user資訊存在cookie中 ,要嘛大家就在逛網站,而不用急著登入。那麼登入真的是最需要被驗證的接口嗎?其實可能不是。這些都端看你網站內的流程如何設計。那往對應到流程後,背後有哪些”最相關的Api分析出來後,就可能是你首要的驗證對象。

因此 使用者場景=分析=>關鍵路徑(常用不一定關鍵)=分解=>背後關鍵的API順序。這個過程去識別出測試對象,就是很重要的。

大則流程,細則程式,你也可以想象,這是一個識別風險的過程,並透過科學的方式證明他們是或不是風險,每次開發好一個API功能後,可能先單獨 驗證這隻API的效能,再接著從這次 新增的Api去往外推論影響的範圍。

最後,聊一下由下而上的概念,這邊舉個例子,就是測試參數到底怎麼決定比較好,看了k6的vus跟duration還有iteration後,我發現測試上會跟現實狀況會有脫勾的情況,例如你要測 2000 concurrent user,你的想像是一秒內同時打 2000個請求,都能被消耗,並能被快速的執行完成,是這樣嗎?往往 使用者情境不見得是這樣,就算是搶票,我們還是可以區分出讀寫比重不一定一樣的行為模式,因此結合使用者情境或是能透過你的情境去解釋,就會各自有差別,不過我想說的以本機測試為例,我們其實是希望知道受測單元的極限。例如1個直接回傳 200的api接口,在一台PC等級的筆電上,能驗證的vus同時併發量就是440vus(因為超過可能就會”環境”failed,是server被reset connection的那種),然後平均每秒 處理請求數是多少,這些都可以先針對你的技術框架有一個單元極限值,然後再往 疊加業務邏輯的方式,去收斂那個參數邊界,最後找到一個合理 測試參數,接著就是固定這個變數,往再去尋找其他可控 變數,例如組合不同邏輯下,對效能、可用性的影響為何 。

知道作法跟想做的方向後,再來看我們要怎麼解讀壓力測試API的結果來回答我們的疑問,現學現賣一下,不外乎想知道兩個面向

  1. Latency(延遲)
  2. Availability(可用性)

從Latency 延遲角度,可以結合Performance的角度就是為了知道有壓力源下的回應時間的分佈狀況。例如你可以想像在早上8:00的時候,使用系統的人最多,可能有1000人,平均等待時間會從100人的平均3秒成長到平均10秒 ,而這樣的延遲是否可以”忍受”。若不能忍受就要提高服務器的性能或是做其他的分流機制。

從Availability可用性的角度,主要是想知道API是否會中止服務,而導致關鍵流程無法完成。因此我認為就是在看 Total跟Failed的比例。假如Fail是3次 ,但是是100萬次的3次,跟10次 裡的3次 ,狀況可能完全不一樣。(但這不代表 100萬的3次 不重要)

可以想像一個情境,假如你有一個搶票的API,公告12:00開始可以進來搶100張票,結果假如你只有一台主機服務,結果因為開搶那一瞬間,湧進來10000個人來搶。瞬間把API打到當機,背後的資料庫也阻塞中止新連線,結果整個網站不要說進來了,連前面有成功進來的人也無法往下走到”金流”的流程,那麼就是典型的可用性出了很大的問題。

而這些都是可以”提前”大膽的假設,透過壓測工具來求證。那麼如何使用工具來驗證場景呢?K6官網有整理了幾種壓測的情境,來因應上述的場景
1.Smoke Test
2.Average Test
3.Stress Test
4.Spike Test
5.Soak Test

其中或許我們只要分辨出,SmokeTest目的是用小單位去驗收你的測試腳本是否正確,先行排除在重點之外。

而Average, Stress, Spike都是在給定一個壓力源(這個也是要設計的)下 ,壓力可能是量,可能是時間長(Soak),到底回應時間以及可用性如何。

上面先啦賽了這麼多,就是希望有助於結構性的先理解我們面對的東西是什麼,概念跟術語是什麼,先做好定義同步共識後,往下做的Action才有理有據,而每一次做的壓測都有如一場實驗,留下的數據,就算是沒有瓶頸的發現,那保留下來的可能那組”安全”參數、數據上的經驗都應該要能夠被延續,而不是把每個壓測都視為那麼單一的事件去操作。每個產品,每個階段,每個功能都不盡相同,但分析與解決問題的脈落其實都有一套科學思維的pattern,數據也有解讀的方式。解讀出來後,如何往下分析瓶頸(依賴)跟重構,那屬於壓測後的獨立工作,就先不在這邊一併討論了。