iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0

簡介

當大家學習演算法時,應該都接觸過時間複雜度的概念(例如 O(n))。當 n 很小時,開發者使用哪種演算法其實差別不大。然而,隨著 n 的增長,效率較差的演算法會導致計算時間顯著增加,進而嚴重影響系統性能。此時,開發者就需要謹慎選擇合適的演算法來解決性能問題。

同樣的情況也可能發生在開發者所維護的 Web Application 中。當使用人數較少時,無論系統設計如何,應用程式通常都能應付現有的負載。然而,隨著使用者數量的逐步增加,系統的瓶頸會逐漸浮現,最終導致使用者發現系統反應速度變慢,甚至可能發生崩潰。

為了避免性能瓶頸影響用戶體驗,開發者需要進行壓力測試,模擬大量同時發出的用戶請求,以便發現並解決性能問題。這與前幾篇文章中進行的測試有所不同。此前的測試主要是為了驗證系統的功能性,確保程式的輸入與輸出符合預期,因此模擬的重點在於創建假資料(Arrange)。

由於壓力測試的重點是模擬大量同時發出的用戶請求,這一過程手動操作幾乎是不可能實現的。即使手動操作,也僅能觸發幾百次請求,遠遠無法達到高負載的需求。因此,我們需要借助壓力測試工具來生成大量模擬用戶並同時發出請求。本次介紹的壓力測試工具 Locust,通過 Python 來編寫壓力測試腳本,對於已經熟悉 Python 的讀者來說,上手會非常容易。接下來,我將通過範例進行具體介紹。

範例

本次範例使用的是 Locust 2.31.8 版本

poetry add locust==2.31.8

Product Code

首先,使用 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)

Test Code

我們需要建立壓力測試的測試代碼。首先,前往 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")

Stress Testing Configuration

首先,在瀏覽器中輸入 localhost:8089,即可看到如下畫面。在這個畫面中,有三個參數需要填寫

  1. Number of users
    這個參數代表壓力測試總共使用者的總數,也就是峰值,本次範例會設為 10000。

  2. Ramp up
    此參數表示每秒增加的使用者數量。在現實的系統使用場景中,流量通常不會瞬間達到峰值,而是逐步增長。通過 ramp up,可以使測試更接近實際情況。例如,在本範例中設置為 100,意味著每秒將增加 100 位使用者,直到達到峰值 10,000 位使用者,之後將一直維持在這一數量。

  3. Host
    此參數指定要測試的網站主機。由於本範例的 Product Code 運行在本地端,因此該參數填寫 http://localhost:5000 即可。

https://ithelp.ithome.com.tw/upload/images/20241011/201686631PriU2G2MX.png

Result

我們可以從 STATISTICS 分頁看到詳細的統計結果,也可以從 CHARTS 分頁看到系統回應時間的增長趨勢。

https://ithelp.ithome.com.tw/upload/images/20241011/20168663pHIvLab9mO.png

https://ithelp.ithome.com.tw/upload/images/20241011/20168663nRtsfgwBSJ.png

https://ithelp.ithome.com.tw/upload/images/20241011/20168663mpjCGTtkjj.png

Note

為了方便大家能夠跟著範例進行操作,本次網頁應用程式和壓力測試工具都在同一台機器上運行。然而,由於兩者會競爭相同的系統資源,因此測試結果可能不準確。在此不針對數據結果進行分析討論。未來如果大家要進行壓力測試,請務必將應用程式和測試工具分別運行在不同的機器上。


上一篇
[Day 27] Flask Test Client
下一篇
[Day 29] Selenium
系列文
Python 不止於數據,開發應用程式它也在行!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言