項目壓測數據

壓測流程

  1. 首先啓動 locust 壓測腳本
  2. 然後啓動bus查分模擬腳本
  3. 收集數據
  4. 壓測結束,清理數據

採集的數據爲:

  1. 請求相關數據,如響應時間,請求總數據量
  2. 資源相關,請求時pod的數量以及實時cpu,內存消耗
  3. 請求數量數量,總請求數量,時間分佈
  4. apm請求記錄,查詢請求具體耗時
  5. 數據庫信息,記錄網絡連接數變化
  6. locust請求端數據總計,錯誤數量,RPS,耗時統計等

單測查詢接口

單獨測試查詢結果的接口,要求:返回時間不超過1s,如果超過1s則添加pod,測試極限壓力

查分實際場景模擬
在查分時有查詢接口和添加准考證,而且還會有查分bus。查實多個接口調用下的各項參數指標。

數據準備
用戶:cettest20~cettest79 共60個
獲取用戶token,保存在redis中,後續請求需要攜帶token發起請求。
注意:該接口只有staging環境才能使用

import requests
import redis

pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)


token_dict = {}
url = "https://apiv3.shanbay.com/bayuser/login"
for i in range(20,80):
    user_name = f"cettest{str(i)}"
    
    payload = {
        "account": user_name,
        "code_2fa":"",
        "password": "123456"
    }
    headers = {"X-API-TOKEN": "IBILiaNGtorE"}
    res = requests.post(url, json=payload, headers=headers)
    if 200 == res.status_code:
        print(user_name)
        token_dict[user_name] = res.cookies.get("auth_token")
    r.hmset("cettest_user_token_dict", token_dict)


print(token_dict)
token_dict_redis = r.hgetall("cettest_user_token_dict")
print(token_dict_redis)

locust 壓測腳本

locust_test.py

import time
import random
import redis
from locust import HttpUser, TaskSet, task, constant_throughput


class UserBehavior(HttpUser):
    wait_time = constant_throughput(2)

    def on_start(self):
        pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
        r = redis.Redis(connection_pool=pool)

        # cettest20~cettest79 共60個測試賬號的token
        self.token_dict = r.hgetall("cettest_user_token_dict")  # 字典 {user_name: token ...}
        self.token_list = [token for token in self.token_dict.values()]
        self.user_list = []
        for i in range(20, 80):
            temp = {}
            temp["name"] = f"cettest{str(i)}"
            temp["ticket"] = str(random.randint(5,9))*15
            temp["phone_num"] = 11111111111
            temp["source_plan_id"] = random.randint(19,20)
            self.user_list.append(temp)

    @task(4)
    def get_user_ticket(self):
        url = "https://apiv3.shanbay.com/tickethub/ticket/user?code=2021-12-cet"
        cookies = {"auth_token": random.choice(self.token_list)}
        self.client.get(url, cookies=cookies)
    
    @task(2)
    def post_user_ticket(self):
        url = "https://apiv3.shanbay.com/tickethub/ticket/user?code=2021-12-cet&is_in_shanbay=1"
        user = random.choice(self.user_list)
        payload = {
            "channel": 0,
            "name": user["name"],
            "phone_num": user["phone_num"],
            "source_plan_id": user["source_plan_id"],
            "ticket": user["ticket"]
        }
        cookies = {"auth_token": self.token_dict[user["name"]]}
        self.client.post(url, cookies=cookies, json=payload)

    @task(1)
    def put_user_ticket(self):
        url = "https://apiv3.shanbay.com/tickethub/ticket/user?code=2021-12-cet&is_in_shanbay=1"
        user = random.choice(self.user_list)
        payload = {
            "name": user["name"],
            "phone_num": user["phone_num"],
            "ticket": user["ticket"]
        }
        cookies = {"auth_token": self.token_dict[user["name"]]}
        self.client.put(url, cookies=cookies, json=payload)

啓動腳本:

locust -f  locust_test.py

訪問:
127.0.0.1:8098 填寫用戶數和每秒增長數
RPS計算:代碼中的 wait_time 是一次請求的間隔時間,爲1表示請求一次間隔1s,RPS爲1。用戶數指開啓的協程數。所以RPS = wait_time * 用戶數
bus 查分模擬腳本
過程:查詢出post請求創建的用戶,調用查分結果的bus寫入分數。
數據特徵:所有測試用戶的手機號都是 11111111111 學校 college爲 "壓測學院"

import time
import random
from app import models as am
from app.buses import send_user_grades


user_tickets = am.UserTicket.select().where(am.UserTicket.phone_num=="bQ8AqNMnFh8pLkOX5tXg9A==")

while True: 
    for user in user_tickets:
        print(f"{user.id}{user.name}")
        user_list = []
        temp = dict()
        temp["name"] = user.name
        temp["ticket"] = user.ticket
        temp["status"] = 0
        temp["reading"] = random.randint(100,300)
        temp["listening"] = random.randint(100,300)
        temp["writing"] = random.randint(100,300)
        temp["total"] = random.randint(300,500)
        temp["school_name"] = "壓測學院"
        temp["exam_level"] = random.randint(0,1)
        user_list.append(temp)
        send_user_grades.delay(user_list)
    time.sleep(5)
    print("*" * 20)

數據清除腳本
根據數據特徵清除測試數據

from app import models as am
user_tickets = am.UserTicket.select().where(am.UserTicket.phone_num=="bQ8AqNMnFh8pLkOX5tXg9A==", am.UserTicket.college=="壓測學院").count()

print(f"將要刪除的用戶數{user_tickets}")
delete_users = am.UserTicket.delete().where(am.UserTicket.phone_num=="bQ8AqNMnFh8pLkOX5tXg9A==", am.UserTicket.college=="壓測學院").execute()
print("刪除的用戶{delete_users}")

基準測試

PRS 10

測試時長:3 min
locust

grafana 請求數量

grafana pod資源

kibana 請求數量

kibana apm

rps 680


grafana 請求相關

grafana 資源相關

kibana 請求數量相關

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章