標籤: Locust

locust + nginx + tornado web server 壓測客戶端與服務端 自動化腳本與實測結果

locust + nginx + tornado web server 壓測客戶端與服務端 自動化腳本與實測結果

壓測是考驗整體架構吞吐量與穩定性的最直接方式

繼上一篇 找到了一個壓測新朋友Locust 傳送門

這一篇進一步透過自動化shell,可以加速建置你的壓測Client端集群與Server端集群

首先我們要租2台主機,讓其物理cpu、ram網卡獨立,然後可以預設在相同的DataCenter,以降低跨DataCenter的網路影響因素

整體壓測概念如下:

 

Initail #number of web server Shell Script

#!/bin/bash

read -p "Enter your webserver number to remove: " p_clear_count

for (( i=1 ; ((i < ($p_clear_count+1))) ; i=(($i+1)) ))
do
  sudo docker rm -f webtest$(printf 0%02d $i)
done;
sudo docker rm -f web-test-nginx

read -p "Enter your webserver number: " p_count

for (( i=1 ; ((i < ($p_count+1))) ; i=(($i+1)) ))
do
  sudo docker run -d --name webtest$(printf 0%02d $i) --network="webtest" -p $(printf 100%02d $i):6969 tornado-web-test
done;

sudo docker run --name web-test-nginx --network="webtest" -p 10000:10000 -v /mnt/nginx/conf.d/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx nginx-debug -g 'daemon off;'

Initail #number of locust client Shell Script

#!/bin/bash

Test_Url="http://{{hostname}}:10000"

read -p "Enter your locust client number to remove: " p_clear_count

for (( i=1 ; ((i < ($p_clear_count+1))) ; i=(($i+1)) ))
do
  sudo docker rm -f locust-slave$i
done;
sudo docker rm -f locust-master

read -p "Enter your locust client number: " p_count

sudo docker run -d --name locust-master --hostname locust-master \
 --network="webtest" \
 -p 8089:8089 -p 5557:5557 -p 5558:5558 \
 -v /mnt/webtest/locust-master:/locust \
 -e LOCUST_MODE=master \
 -e ATTACKED_HOST="$Test_Url" \
 grubykarol/locust

for (( i=1 ; ((i < ($p_count+1))) ; i=(($i+1)) ))
do
  sudo docker run -d --name locust-slave$i \
	 --network="webtest" \
	 --env NO_PROXY=locust-master \
	 -e ATTACKED_HOST="$Test_Url" \
	 -v /mnt/webtest/locust-slave:/locust \
	 -e LOCUST_MODE=slave \
	 -e LOCUST_MASTER=locust-master \
	 --rm grubykarol/locust
done;

 

實測下來,8g開10個container(共享)的情況下,估計10000 concurrent user應該已經是很極限了,其實我們會發現極限應該是會在client發出請求端

web server多少會因為os、網卡、容器網路的限制,導致同時connection數無法無限上崗,而web server的運作還不包含更複雜的運算情境(只考慮in ram處理與非同步mongodb log)

因此以此為基準來當作未來擴充的計算基礎參考,應該還ok,若要模擬更複雜的商業邏輯運作,那麼可以仿照此作法去刻

10k

20k (RPS反而降了,看來還是有其極限存在)

美中不足的就是怎麼動態改Nginx的Nginx.Conf,把ReversProxy動態換掉,這個以後再研究吧…

 

100k on AWS
Reference:
1.https://aws.amazon.com/tw/blogs/devops/using-locust-on-aws-elastic-beanstalk-for-distributed-load-generation-and-testing/
2.https://www.slideshare.net/AmazonWebServices/aws-reinvent-2016-how-to-launch-a-100kuser-corporate-back-office-with-microsoft-servers-and-aws-win303?from_action=save

壓測工具的新選擇!! Locust load test framework

壓測工具的新選擇!! Locust load test framework

繼上一篇,自建nginx分流後(傳送門),接著的問題就是要如何驗證分流效果與實際上這樣架構的負載吞吐量到底能到多少了。傳統想到壓測,我們就會想到jmeter,但是jmeter的參數配置繁多,而且若要做到可程式化的話其路可能相當曲折;再者,若在我們實體主機上測試的話,極有可能受限於其物理極限,包含頻寬與網卡的能力,因此我搜尋了一下python有沒有load test framework,又可以同時支援分散式的load test

 

結果發現了這套名叫:locust的套件!!其安裝方式相當的簡單:

首先,整份框架都是python寫的,透過pip就可以安裝,因此先來試著打包成映像檔,變成隨時可以使用的容器吧:

測試Script寫起來相當簡潔,我們直接存成locustfile.py,實作HttpLocust、TaskSet後,屆時會在locust的壓測ui介面,讀取到接口

from locust import HttpLocust, TaskSet, task


class WebTest(TaskSet):

    @task
    def get_uuid(self):
        self.client.get("/webtest?action=get_uuid")


class WebsiteTest(HttpLocust):
    task_set = WebTest

Dockerfile的內容:

FROM python:3.6-alpine

COPY docker-entrypoint.sh /

RUN    apk --no-cache add --virtual=.build-dep build-base \
    && apk --no-cache add libzmq \
    && pip install --no-cache-dir locustio==0.8.1 \
    && apk del .build-dep \
    && chmod +x /docker-entrypoint.sh

RUN  mkdir /locust
WORKDIR /locust
EXPOSE 8089 5557 5558

ENTRYPOINT ["/docker-entrypoint.sh"]

docker-entrypoint.sh的內容:

#!/bin/sh
set -e
LOCUST_MODE=${LOCUST_MODE:-standalone}
LOCUST_MASTER_BIND_PORT=${LOCUST_MASTER_BIND_PORT:-5557}
LOCUST_FILE=${LOCUST_FILE:-locustfile.py}

if [ -z ${ATTACKED_HOST+x} ] ; then
    echo "You need to set the URL of the host to be tested (ATTACKED_HOST)."
    exit 1
fi

LOCUST_OPTS="-f ${LOCUST_FILE} --host=${ATTACKED_HOST} --no-reset-stats $LOCUST_OPTS"

case `echo ${LOCUST_MODE} | tr 'a-z' 'A-Z'` in
"MASTER")
    LOCUST_OPTS="--master --master-bind-port=${LOCUST_MASTER_BIND_PORT} $LOCUST_OPTS"
    ;;

"SLAVE")
    LOCUST_OPTS="--slave --master-host=${LOCUST_MASTER} --master-port=${LOCUST_MASTER_BIND_PORT} $LOCUST_OPTS"
    if [ -z ${LOCUST_MASTER+x} ] ; then
        echo "You need to set LOCUST_MASTER."
        exit 1
    fi
    ;;
esac

cd /locust
locust ${LOCUST_OPTS}

單一台load test測試端 啟動指令 (驗證ok):

sudo docker run --name locust-master --hostname locust-master \
--network="webtest" \
-p 8089:8089 -p 5557:5557 -p 5558:5558 \
-v /home/paul/webtest/locust:/locust \
-e ATTACKED_HOST='http://web-test-nginx:10000' \
grubykarol/locust

分散式的測試端配置(待驗證):

啟動指令-master測試端:

docker run --name master --hostname master `
 -p 8089:8089 -p 5557:5557 -p 5558:5558 `
 -v c:\locust-scripts:/locust `
 -e ATTACKED_HOST='http://master:8089' `
 -e LOCUST_MODE=master `
 --rm -d grubykarol/locust

啟動指令-slave測試端:

docker run --name slave0 `
 --link master --env NO_PROXY=master `
 -v c:\locust-scripts:/locust `
 -e ATTACKED_HOST=http://master:8089 `
 -e LOCUST_MODE=slave `
 -e LOCUST_MASTER=master `
 --rm -d grubykarol/locust
docker run --name slave1 `
 --link master --env NO_PROXY=master `
 -v c:\locust-scripts:/locust `
 -e ATTACKED_HOST=http://master:8089 `
 -e LOCUST_MODE=slave `
 -e LOCUST_MASTER=master `
 --rm -d grubykarol/locust

 

容器執行後,打入http://xxx.xxx.xxx.xxx:8090,就可以連到對應的監控網址(這個是最棒的),一開始就會問你模擬的u數,以及你希望多久時間內要衝到該u數

摘要總表:

即時圖表:

錯誤分析:

 

同時,我去驗證了我們mongodb的log,是符合他load test的請求數量

 

以上是這次接觸到新的壓測工具實作的小小記錄,也推薦給大伙

 

參考:

https://locust.io/

https://docs.locust.io/en/stable/

https://medium.com/locust-io-experiments/locust-io-experiments-running-in-docker-cae3c7f9386e