环境:python3.6.8 + locust 2.4.1 + Go(go1.17.2) + Boomer
压测工具:
1)loadRunner: 功能强大,付费,使用复杂;
2)jmeter: 很难在单机上模拟比较高的并发压力;
3)Locust (1个master-多个slave ): 扩展性更强, Python描述测试脚本, http请求完全基于requests库,可自定义开发, 支持多种协议的压测。 在相同配置服务器资源下,能产生更大的压力,协程避免系统级资源调度。
4)Boomer (go 版本,go改写locust, 由Python-Gevent -> Go -Goroutine, 提高高并发的能力。 Python受限制于GIL锁,用go版本作为slave,并发能力更好。
最近学习GO, 尝试本机搭建一套boomer压测系统,记录步骤及主要问题:
一、环境安装
1. 安装Python:安装成功后添加环境变量,2个路径加到path中:
1) 安装路径\Python36\Scripts
2) 安装路径\Python36
2. 安装locust: pip install locustio (镜像源是国外的, 可以带上超时时间参数: --timeout=200
--timeout <sec> Set the socket timeout (default 15 seconds).
安装成功后,CMD执行命令查看安装版本: locust -V(如果提示命令不认识,关闭窗口再打开试下)
3. 安装go环境 + boomer : 参考之前的记录
二、 Demo(master : locust , slave: Boomer)
1. 启动master :
locust --master -f prometheus_exporter.py --web-host="127.0.0.1"
Boomer包路径下有prometheus_exporter.py文件,写好的/export/prometheus 扩展接口采集压测数据。直接将该脚本作为master启动,访问:
1)http://127.0.0.1:8089/ : 压测客户端, worker是0
2)http://localhost:8089/export/prometheus :可以看到采集的压测数据
2. Go编写压测端启动:
go run github.com\myproject\main.go -url="https://www.baidu.com"
package main
import (
"flag"
"github.com/gin-gonic/gin"
"github.com/myzhan/boomer"
"io/ioutil"
"net/http"
"time"
)
var URL string
func demo1() {
start := time.Now()
url := URL + "/"
resp, err := http.Get(url)
if err != nil {
println(err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
elapsed := time.Since(start)
if resp.Status == "200 OK" {
boomer.RecordSuccess("Get", "/", elapsed.Nanoseconds()/int64(time.Millisecond), resp.ContentLength)
}else {
boomer.RecordFailure("Get", "/", elapsed.Nanoseconds()/int64(time.Millisecond), resp.Status + string(body))
}
}
func demo2() {
start := time.Now()
url := URL + "/"
resp, err := http.Get(url)
if err != nil {
println(err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
elapsed := time.Since(start)
if resp.Status == "200 OK" {
boomer.RecordSuccess("Get", "/hello", elapsed.Nanoseconds()/int64(time.Millisecond), resp.ContentLength)
}else {
boomer.RecordFailure("Get", "/hello", elapsed.Nanoseconds()/int64(time.Millisecond), resp.Status + string(body))
}
}
func main() {
flag.StringVar(&URL, "url", "", "url") // 命令行参数解析
flag.Parse()
task1 := &boomer.Task{
Name: "demo1",
Weight: 10,
Fn: demo1,
}
task2 := &boomer.Task{
Name: "demo2",
Weight: 10,
Fn: demo2,
}
boomer.Run(task1, task2)
}
3. 压测客户端运行压测
压测客户端及数据采集可以看到压测情况:
4. 采集的数据给Prometheus + Grafana 做大盘报表展示,可以参考:
https://testerhome.com/topics/31360
三、问题记录
1. 安装好locust, 编写demo.py , 启动后locust客户端监控页面打不开
locust下argument_parser.py文件中,--web-host的default="",需要在命令后增加--web-host指定地址 :locust -f .\demo.py --web-host="127.0.0.1"
web_ui_group.add_argument(
"--web-host",
default="",
help="Host to bind the web interface to. Defaults to '*' (all interfaces)",
env_var="LOCUST_WEB_HOST",
)
# demo.py
from locust import HttpUser, TaskSet, task, between
class NoSlowQTaskSet(HttpUser):
host = "https://www.baidu.com/"
@task
def index_page(self):
r = self.client.get("/")
2. .