當大家學習演算法時,應該都接觸過時間複雜度的概念(例如 O(n))。當 n 很小時,開發者使用哪種演算法其實差別不大。然而,隨著 n 的增長,效率較差的演算法會導致計算時間顯著增加,進而嚴重影響系統性能。此時,開發者就需要謹慎選擇合適的演算法來解決性能問題。
同樣的情況也可能發生在開發者所維護的 Web Application 中。當使用人數較少時,無論系統設計如何,應用程式通常都能應付現有的負載。然而,隨著使用者數量的逐步增加,系統的瓶頸會逐漸浮現,最終導致使用者發現系統反應速度變慢,甚至可能發生崩潰。
為了避免性能瓶頸影響用戶體驗,開發者需要進行壓力測試,模擬大量同時發出的用戶請求,以便發現並解決性能問題。這與前幾篇文章中進行的測試有所不同。此前的測試主要是為了驗證系統的功能性,確保程式的輸入與輸出符合預期,因此模擬的重點在於創建假資料(Arrange)。
由於壓力測試的重點是模擬大量同時發出的用戶請求,這一過程手動操作幾乎是不可能實現的。即使手動操作,也僅能觸發幾百次請求,遠遠無法達到高負載的需求。因此,我們需要借助壓力測試工具來生成大量模擬用戶並同時發出請求。本次介紹的壓力測試工具 Locust,通過 Python 來編寫壓力測試腳本,對於已經熟悉 Python 的讀者來說,上手會非常容易。接下來,我將通過範例進行具體介紹。
本次範例使用的是 Locust 2.31.8 版本
poetry add locust==2.31.8
首先,使用 poetry new demo_locust
建立專案目錄,然後進入 demo_locust/demo_locust
目錄下,並建立 app.py
。這個 Product Code 是一個簡單的 Flask Web Application,包含一個 HTTP GET 端點,使用者可以通過該端點發送請求來獲取所有商品資訊。最後,執行 poetry run flask run
來啟動這個 Product Code。
from flask import Flask
app = Flask(__name__)
@app.route("/products")
def get_products():
return [
{"name": "Apple", "price": 30},
{"name": "Orange", "price": 25},
{"name": "Phone", "price": 30000},
{"name": "TV", "price": 48888},
{"name": "Toilet Paper", "price": 299},
{"name": "Earphone", "price": 6000},
]
if __name__ == "__main__":
app.run(debug=True)
我們需要建立壓力測試的測試代碼。首先,前往 demo_locust/tests
目錄,然後建立 locustfile.py
。在這個檔案中,我們需要繼承 HttpUser
類別並自定義壓力測試的邏輯。該類別主要有兩個區塊,首先介紹下方的 get_products
函式。唯有加上 @task
Decorator 的函式會被視為壓力測試的執行任務,這個任務將模擬發出請求以獲取商品資訊。
此外,上方的 wait_time = between(1, 5)
代表任務執行的間隔時間,通常會設置為數秒,以模擬正常使用者的使用情境。最後,執行 poetry run locust
即可開始運行測試代碼。
from locust import HttpUser, between, task
class GetProductsUser(HttpUser):
wait_time = between(1, 5)
@task
def get_products(self):
self.client.get("/products")
首先,在瀏覽器中輸入 localhost:8089
,即可看到如下畫面。在這個畫面中,有三個參數需要填寫
Number of users
這個參數代表壓力測試總共使用者的總數,也就是峰值,本次範例會設為 10000。
Ramp up
此參數表示每秒增加的使用者數量。在現實的系統使用場景中,流量通常不會瞬間達到峰值,而是逐步增長。通過 ramp up
,可以使測試更接近實際情況。例如,在本範例中設置為 100,意味著每秒將增加 100 位使用者,直到達到峰值 10,000 位使用者,之後將一直維持在這一數量。
Host
此參數指定要測試的網站主機。由於本範例的 Product Code 運行在本地端,因此該參數填寫 http://localhost:5000
即可。
我們可以從 STATISTICS
分頁看到詳細的統計結果,也可以從 CHARTS
分頁看到系統回應時間的增長趨勢。
為了方便大家能夠跟著範例進行操作,本次網頁應用程式和壓力測試工具都在同一台機器上運行。然而,由於兩者會競爭相同的系統資源,因此測試結果可能不準確。在此不針對數據結果進行分析討論。未來如果大家要進行壓力測試,請務必將應用程式和測試工具分別運行在不同的機器上。