試用 Load testing 工具 - Drill

Drill 是一個以程式語言 Rust 撰寫的輕量級 HTTP Load testing 工具,Load testing 工具百百款,之所以會特別想認識 Drill 則是因為該工具的一段簡介「You can write benchmark files, in YAML format, describing all the stuff you want to test. It was inspired by Ansible syntax because it is really easy to use and extend.

看到上面那段簡介,身為 Ansible 的使用者,怎麼可以不來驗證一下,是不是真的如它所言!

(本文撰寫時,使用的 Drill 版本為 0.7.1。)

(本文同步發表於 Medium。)

操作步驟

我們知道試用任何工作的第一步是先看官方文件!

錯!當然是先看有沒有已經包好立即可用的 Container image!(咦)

可惜在撰文的當下,尚未看見官方有自己包好 Container image,在 Docker Hub 只有找到 Drill 版本 0.5.0 的 Docker image。

由於沒有最新版的 Container image,只好自己 build 一個,這邊就偷懶不追求 Container Size 的最小化,先搶快做出 Drill 0.7.1 版本的 Image。

# Dockerfile

FROM rust:1.53

RUN apt-get update && \
    apt-get install -y curl libssl-dev pkg-config && \
    rm -rf /var/lib/apt/lists/*

RUN cargo install drill

用上面這個 Dockerfile 建出來的 Docker image 會高達 1.4GB,建議大家還是要自己另外 build 一個最小化的 Image。

搞定 Docker image,接著就按官方文件開始撰寫 Drill 的 Benchmark file。

撰寫基本的 Benchmark file

Drill 的 Benchmark file 採用 YAML 格式。想要對哪個 URL 實施 Load testing、要測試 GET 或 POST、測試的強度及頻率⋯⋯全都設置在同一個 YAML 檔案即可。下面就嘗試撰寫一個最簡單的 Benchmark file。

首先是四個基本項目。

# 要檢測的目標網址。
base: 'https://gitlab-book.tw'

# 重複執行多少次
iterations: 100

# 同時並行檢測的數量
concurrency: 4

# 多久時間內要提升至前項設定的並行數量
rampup: 5

以上面的設定為例,即是模擬從 1 開始至多 4 個人同時連續嘗試連上 https://gitlab-book.tw 這個網站。

不過 base: 只是檢測目標的 Base URL,並非實際施測的 URL,真正想要施測的內容,我們要接續寫在 plan: 中。

base: 'https://gitlab-book.tw'
iterations: 100
concurrency: 4
rampup: 5

# 施測內容需撰寫在 plan: 之下
plan:
- name: Test URL | home 
  request:
    url: /
- name: Test URL | home 
  request:
    url: /about.html

如上範例,屆時執行 drill 實施 Load testing 時,Drill 就會對 https://gitlab-book.tw/https://gitlab-book.tw/about.html 這兩個 URL 發出 Request。

首次執行 drill

接著嘗試執行,不過一開始不要太激烈,所以將 iterations:concurrency:rampup: 都改回 1,存檔命名為 benchmark.yml 先實驗一下。

drill -b benchmark.yml

結果非常單純,如下圖。 drill result

接著補上參數 --stats,讓 Drill 呈現更多的完整數據。

drill -b benchmark.yml --stats

drill result

再來改用 --report 試著輸出 report。

drill -b benchmark.yml --report myreport.yml

Report 也是 YAML 格式

drill report

試著調高測試數據,iterations: 改成 10。如下圖,確實兩個 URL 都被戳了 10 下。

drill result

最下方的統計數據也確實有詳盡計算。

drill result

改成 concurrency: 4 的狀況又是如何呢。可以看見總次數依然是 10 次,但會是一次並列送出 4 個 Request。

drill result

最後來加大力道吧!(謎之音:好弱的加強力道,才 100 而已。)

iterations: 100
concurrency: 4
rampup: 4

這裡就只截圖最後的數據。

drill result

Drill Benchmark file 與 Ansible 相似的地方

從官方文件可以發現,Drill 的 Benchmark file 確實有一些地方與 Ansible 類似,這邊就來實驗幾個很明顯的。

  • {{ }} 印出 Variables

例如 plan: 內的 request name 可以這樣修改。

- name: "Test URL | home {{ iteration }}"
  request:
    url: /

屆時執行結果就會這樣呈現。

drill result

  • with_items: 來動態變更 url:

例如將 Benchmark file 修改。

plan:
- name: "Test URL | {{ item }} {{ iteration }}"
  request:
    url: "{{ item }}"
  with_items:
  - "/"
  - "/about.html"

一樣能對多個 URL 施測,執行結果類似下圖。

drill result

  • include: 可以將 benchmark file 切分多個檔案,方便管理。

例如將 GET 與 POST 兩種類型的 Request 分開管理。

plan:
- name: "Include url"
  include: get.yml

- name: "Include url"
  include: post.yml
  • 可以建立 Variables,後續取出來運用
- name: Assign values
  assign:
    key: create_variable
    value: "/about.html"

- name: TEST
  request:
    url: "{{ create_variable }}"

drill result

  • 可以將某個 Request 的結果,儲存為 Variable,再拿出來使用
plan:

# 第一個 Request 先去戳 API,然後將取得的內容註冊為 api_data
- name: Get Json Data
  request:
    url: "/some-api"
  assign: api_data

# 第二個 Request 就可以直接取出 api_data 得到的內容,並直接用於 url:
- name: Test
  request:
    url: "{{ api_data.body.some-column }}"

其他還有別的地方與 Ansible 類似,就不全部一一列舉,有興趣者可以自行詳閱官方文件與範例。

結語

當初是在《Top 10 HTTP Benchmarking and Load Testing Tools》這篇文章中看見 Drill 這項 Load testing 工具。就如文章開頭所述,當時我就已經被它的介紹文打中,想不到居然有其他的工具會受到 Ansible 的格式啟發,在快速看過官方文件後發現還真的有相似之處,便決定有機會一定要來試用看看。

雖然這次試用並沒有詳細的將 Drill 與其他的 Load testing 工具做比較,像是工具運行時會消耗多少資源?可以用來測試多大的情境?但老實說光是可以用類似 Ansible 語法的 YAML 格式來撰寫測試案例,這一點就已打中我的心,感覺上即使不將 Drill 作為 Load testing 工具,僅是將它放進 CI/CD Pipeline 中當作網站部署後的自動檢測工具,應該也是一個可以考慮的選擇。

啊,不過在那之前,先拜託來個好心人幫官方 build 一個 Size 小一點的 Container Image 吧!

參考資料

更多文章