当前位置: 首页 > news >正文

golang实现的ab测试http代理工具

压测工具ab不能统计http请求的错误情况,包括http状态码错误和响应正文的错误关键字。

所以加层代理用于统计http错误情况,重在统计错误情况,而不是代理的性能,主要用于功能接口的测试,比如测试一下请求多少次接口会返回空数据。

被认为是错误的情况

1、非200状态码

2、响应正文里不包含表示正确关键字

3、响应正文里包含表示错误关键字

编译方式:

go build go_ab_proxy.go

启动方式:

./go_ab_proxy

./go_ab_proxy -okstr 'code":"0'

./go_ab_proxy -failstr error

测试方式:

ab -c 2 -n 10 -X 127.0.0.1:9090 'http://www.baidu.com/'

curl -x 127.0.0.1:9090 'http://www.baidu.com/'

查看错误统计:

ctrl-c或kill结束进程时显示统计结果。

golang代码如下:

go_ab_proxy.go

package mainimport ("bytes""flag""fmt""net/http""net/http/httputil""os""os/signal""strings""sync/atomic""syscall"
)var (successCount int32failCount    int32okStr        = flag.String("okstr", "", "indicate ok string")failStr      = flag.String("failstr", "", "indicate fail string")
)func main() {flag.Parse()if *okStr != "" && *failStr != "" {fmt.Printf("-okstr and -failstr only one can be used\n")return}http.HandleFunc("/", middleware(func(w http.ResponseWriter, r *http.Request) {proxy := httputil.NewSingleHostReverseProxy(r.URL)proxy.ServeHTTP(w, r)}))go installSignal()err := http.ListenAndServe(":9090", nil)if err != nil {fmt.Printf("proxy server start fail, %v\n", err)return}
}func middleware(handler http.HandlerFunc) http.HandlerFunc {return func(response http.ResponseWriter, request *http.Request) {responseWrapper := &ResponseWithRecorder{ResponseWriter: response,StatusCode:     http.StatusOK,Body:           bytes.Buffer{},}handler(responseWrapper, request)if responseWrapper.StatusCode != http.StatusOK {atomic.AddInt32(&failCount, 1)} else {if *okStr == "" && *failStr == "" {atomic.AddInt32(&successCount, 1)return}resBody := string(responseWrapper.Body.Bytes())if *okStr != "" && !strings.Contains(resBody, *okStr) {atomic.AddInt32(&failCount, 1)return} else if *failStr != "" && strings.Contains(resBody, *failStr) {atomic.AddInt32(&failCount, 1)return}atomic.AddInt32(&successCount, 1)}}
}func installSignal() {sigs := make(chan os.Signal, 1)signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)go func() {<-sigsfmt.Printf("successCount=%d, failCount=%d\n", atomic.LoadInt32(&successCount), atomic.LoadInt32(&failCount))os.Exit(0)}()
}type ResponseWithRecorder struct {http.ResponseWriterStatusCode intBody       bytes.Buffer
}func (rec *ResponseWithRecorder) WriteHeader(statusCode int) {rec.ResponseWriter.WriteHeader(statusCode)rec.StatusCode = statusCode
}func (rec *ResponseWithRecorder) Write(d []byte) (n int, err error) {n, err = rec.ResponseWriter.Write(d)if err != nil {return}rec.Body.Write(d)return
}

--end--

http://www.lryc.cn/news/403347.html

相关文章:

  • Maven学习——Maven的下载、安装与配置(详细攻略!)
  • C#知识|账号管理系统-修改账号按钮功能的实现
  • bug等级和优先级
  • 记录|C# winform布局学习
  • C/C++ json库
  • C++案例四:简易记事本程序
  • 【VUE学习】day03-过滤器filter
  • 技术成神之路:设计模式(八)责任链模式
  • 【Zynq UltraScale+ RFSoC】~~~
  • STM32之八:IIC通信协议
  • mysql的数据往hive进行上报时怎么保证数据的准确性和一致性
  • 问题:4、商业保险与政策性保险的主要不同之处是:经营主体不同、经营目标不同、承保机制不同。 #学习方法#其他#学习方法
  • Getx学习笔记之中间件鉴权
  • 介绍 Elasticsearch 中的 Learning to Tank - 学习排名
  • 2024年计算机软考中级【硬件工程师】面试题目汇总(附答案)
  • ThinkPad改安装Windows7系统的操作步骤
  • 微软Edge浏览器全解析教程
  • 【过题记录】7.20
  • Linux系统学习日记——vim操作手册
  • 【深度学习图片】图片清洗,只留下图像中只有一张人脸的,而且人脸是全的
  • 如何在 PostgreSQL 中处理海量数据的存储和检索?
  • 【中项】系统集成项目管理工程师-第2章 信息技术发展-2.2新一代信息技术及应用-2.2.1物联网与2.2.2云计算
  • Redis集群的主从复制原理-全量复制和增量复制-哨兵机制
  • 23年阿里淘天笔试题 | 卡码网模拟
  • 【SpringBoot】单元测试之测试Service方法
  • 剪辑师和小白都能用的AI解说神器,一键把短剧变解说视频-手把手教程-2024
  • 我去,怎么http全变https了
  • IDEA的详细设置
  • 为什么Spring选择使用容器来管理对象,而不是直接使用new
  • 腾讯云发送短信验证码