Leo Yeh's Blog

SAS Viya (126)

教學目標

初步了解如何針對 SAS Viya 分析平台所提供的 REST API 進行壓力測試的基本概念。

重點概念

首先 SAS Viya 分析平台提供非常完整的 REST API 服務,但是針對提供給客戶的 REST API 服務上線之前必須要經過壓力測試,而 Apache JMeter 和 Locust 主要是目前主流使用最受歡迎的壓力測試工具,至於主要差別,請參考下表。

JMeter Locust
支援開發語言 Java Python
監控執行方式 Console,Desktop Client,Custom Plugins Console, Web
資源使用情況 More resources required Less resources required

若是應用程式客製開發以 Java 程式語言為主,則建議使用 JMeter,但若是應用程式客製開發以 Python 程式語言為主,則建議使用 Locust。個人建議使用 Locust ,主要有三個原因,第一個原因為使用 Python 程式開發語言,第二個原因為提供網站監控畫面,第三個原因使用較少的資源就能夠進行壓測。此外 Google Cloud Platform (GCP) 雲端平台官方文件也提到使用以 Python 為基礎的分散式工作負載測試工具 Locust,將要求分配至多個目標路徑,並且整合使用 Google Kubernetes Engine (GKE) 部署分散式工作負載測試架構,更進一步用於物聯網 (IoT) 應用程式的壓力測試。

接著我們要如何開始安裝 Locust 呢?其實很簡單僅需要執行 pip 指令就能夠進行立即進行安裝 Locust 套件,其主要用於 Python 程式碼中使用。

安裝 Locust 套件

1
$ pip install locustio

所謂 Locust 主要是一個開放源始碼效能評估的工具,其主要使用 Python 程式碼來定義使用者,並且模擬數百萬的平行使用者來存取我們的系統。但是為何稱為 Locust,Locust 中文意義為蝗蟲,其代表在測試期間會有一群蝗蟲 (A swarm of locusts) 會攻擊我們的網站系統,並且我們能夠定義了每個蝗蟲行為,並且即時地從網站界面監控 Locust 叢集的過程,將有助於我們在讓真正的使用者開始存取系統之前對系統進行測試和識別瓶頸。此外 Locust 完全基於事件,因此可以在一台機器上支援數千個平行使用者,與許多其它基於事件的應用程序相比,其不使用回調 (Callback),並且透過 gevent 函式庫實現極高平行執行能力,並且 gevent 是一個基於協程的 Python 網路庫,其主要使用 greenlet 所提供的進階同步 API,而每個蝗蟲將會蜂擁至我們的網站中,實際上是在本身處理程序內執行,所以我們能夠在 Python 中撰寫非常富有表現力的場景,而不會使得程式碼與回調複雜化,請注意安裝 Locust 套件將會相依以下相關套件,分別為:

  1. gevent 1.2.2:主要用於執行平行處理的套件。
  2. flask 0.10.1:主要用於網站開發框架。
  3. requests 2.9.1:主要用於 HTTP(S) 的存取。
  4. msgpack-python 0.4.2:主要用於快速和緊湊的二進位格式。
  5. six 1.10.0:主要提供簡單的工具封裝 Python2 和 Python3 之間的差異。
  6. pyzmq 16.0.2:主要用於分散式在多個程序或多個機器平行處理多個測試任務

再來我們需要撰寫 Locust 的 Python 程式碼,也就是所謂 Locust 的腳本,其中定義使用者操作行為的 TaskSet 類別主定義了每個使用者的測試任務集合,當測試任務集合開始之後,Locust 會從多個 TaskSet 中隨機挑選使用者的測試任務,此時如果有定義任務之間的權重關係,則會按照權重關係隨機挑選一個任務執行,然後隨機等待所設定的 min_wait 和 max_wait 之間的一段時間,執行下一個測試任務。此外上述範例程式碼主要是以 SAS Viya 平台中的 SAS Micro Analytic Service (MAS) 的評分 REST API 進行影像檔分類的評分測試任務,僅供參考之用。

撰寫 Locust 腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# coding=utf-8
import requests
from locust import HttpLocust,TaskSet,task
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# 初始化 SAS Viya 分析平台的 REST API 存取設定
from io import BytesIO
from PIL import Image
import requests, json, requests, base64, cv2, time, time
import numpy as np
url = 'http://<SAS_Viya_URL>/SASLogon/oauth/clients/consul?callback=false&serviceId=app'
headers = {'X-Consul-Token': '<Consul_Token>'}
r = requests.post(url, headers=headers)
access_token = json.loads(r.text)['access_token']
url = 'http://<SAS_Viya_URL>/microanalyticScore/modules/<Model_Name>/steps/<Model_Method>'
headers = {'Content-Type': 'application/json;charset=utf-8','Authorization': 'Bearer ' + access_token}
with open("<Image_File_Path>", "rb") as imageFile:
image_b64 = base64.b64encode(imageFile.read())
image_b64_utf8 = image_b64.decode("utf-8")
data = {"version":1,"inputs":[{"name":"image_b64","value":image_b64_utf8}]}
r = requests.post(url, headers=headers, json=data)
# 定義使用者操作行為,其中所有請求皆是基於 requests 套件
# client.get => requests.get
# client.post => requests.post
class SASVIYAAPI(TaskSet):
# task 裝飾該方法為一個交易方法的參數用於指定該行為的執行權重,若參數越大,則每次被虛擬使用者執行的機率就越高,預設值為 1
@task(1)
def get_api(self):
header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}
req = self.client.post(url, headers=header, json=data, verify=False)
if req.status_code == 200:
print("success")
else:
print("fails")

# 進行效能測試相關設定,並且指定所定義的使用者行為,以及執行請求之間的等待時間,單位為毫秒
class websitUser(HttpLocust):
task_set = SASVIYAAPI
min_wait = 3000
max_wait = 6000

if __name__ == "__main__":
import os
os.system("locust -f locusttest.py --host=http://<SAS_Viya_URL>")

最後我們將能夠透過以下指令啟動 Locust 測試網站操作介面,預設啟用的連接埠為 8089,所以我們開啟瀏覽器輸入「 http://<Locust_Server_IP>:8089/ 」網址,此時僅需要輸入模擬虛擬使用者的總數 (Number of users to simulate) 和每秒啟動的虛擬使用者數 (Hatch rate),再按下「Start swarming」鈕就能夠立即開始進行壓力測試,同時在壓力測試過程中,除了顯示每秒總請求數、平均回應時間和虛擬使用者執行數量的即時圖表之外,更會顯示即時統計以下資訊,以利進行匯出 csv 檔進行比較,分別為:

  1. Type:請求的類型。
  2. Name:請求的路徑。
  3. #requests:目前請求的數量。
  4. #fails:目前請求失敗的數量。
  5. Median (ms):伺服器回應時間的中位數,單位為毫秒。
  6. Average (ms):伺服器所有請求的平均回應時間,單位為毫秒。
  7. Min (ms):伺服器所有請求的最小回應時間,單位為毫秒。
  8. Max (ms):伺服器所有請求的最大回應時間,單位為毫秒。
  9. Content Size:伺服器單個請求的內容大小。
  10. #reqs/sec:每秒請求數 (RPS),類似每秒交易數 (TPS) 和每秒查詢數 (QPS)。

啟動 Locust 測試網站操作介面

1
$ locust --host=https://<SAS_Viya_URL> --locustfile locustfile.py

然而為了撰寫嚴僅的測試報告,實務上我們不會採用網站操作界面,而是會透過指令的方式來進行自動化壓力測試,其中主要需要設定五個重要的參數,分別為:

  1. —no-web:設定不使用網站操作界面進行測試。
  2. -c:設定虛擬使用者的總數。
  3. -r:設定每秒啟動虛擬使用者的數量。
  4. -t:設定執行測試任務的時間。
  5. —csv:設定測試結果的檔案名稱。

啟動 Locust 自動化壓力測試

1
$ locust --host=https://<SAS_Viya_URL> --locustfile locustfile.py --no-web -c 1000 -r 1 -t10m --csv=sasviyaapi

當完成啟動 Locust 自動化壓力測試之後,將會產生「sasviyaapi_requests.csv」和「sasmas_distribution.csv」兩個測試統計結果的檔案,其中「sasviyaapi_requests.csv」主要是即時統計以下資訊的最後結果輸出,而「sasmas_distribution.csv」主要是提供整個執行過程中有關分佈中 90% 的回應時間等資訊。

總結若我們以 SAS Viya 作為企業的分析平台,並且任何 App 皆會透過 REST API 存取 SAS Viya 分析平台中的運算資源時,則在 App 正式上線之前針對 REST API 的壓力測試就會非常重要。

相關資源

⬅️ Go back