压测程序
发布于: 2020 年 07 月 22 日
-----------------------------------------------------------------------------
代码实现:
package mainimport (	"fmt"	"io/ioutil"	"net/http"	"os"	"sort"	"strconv"	"sync"	"time")var MAX_UINT64 uint64 = ^uint64(0)var (	pressureTimes    int    = 100 //压测次数	pressureDruation int    = 3   // 单次压测时间(单位:秒)	goroutineCnt     int    = 10	Url              string = "https://www.baidu.com" // 请求压测链接	httpTimeout      uint   = 10                      // http超时)// 记录http请求结果type UrlResult struct {	code     int   // http错误码;0为请求错误	costTime int64 // 响应时间}type UrlResultType []*UrlResultfunc (n UrlResultType) Len() int {	return len(n)}func (n UrlResultType) Swap(i, j int) {	n[i], n[j] = n[j], n[i]}func (n UrlResultType) Less(i, j int) bool {	return n[i].costTime < n[j].costTime}func httpGet(url string, timeout uint) (code int) {	code = 0	client := &http.Client{		Timeout: time.Duration(timeout) * time.Second,	}	resp, err := client.Get(url)	if err != nil {		fmt.Printf("http get err, url=%s\n", url)		return	}	defer resp.Body.Close()	if resp.StatusCode != 200 {		fmt.Printf("resp status=%v, url=%s\n", resp.Status, url)		return	}	_, err = ioutil.ReadAll(resp.Body)	if err != nil {		fmt.Printf("resp ReadAll err : %s\n", err)		return	}	code = resp.StatusCode	return}// http请求,并记录请求信息func httpRequest(url string, timeOut uint) (resp *UrlResult) {	// 记录压测信息	defer func(begin_time int64) {		resp.costTime = time.Now().UnixNano()/1e6 - begin_time	}(time.Now().UnixNano() / 1e6)	resp = &UrlResult{}	resp.code = httpGet(url, timeOut)	return}func Stress(goroutineCnt int, runtime int) (respTime int64, average float64, all int) {	var total uint64 = 0	respList := UrlResultType{}	var wg sync.WaitGroup	for i := 0; i < goroutineCnt; i++ {		wg.Add(1)		go func() {			defer wg.Done()			begin_time := time.Now().Second()			for {				resp := httpRequest(Url, httpTimeout)				respList = append(respList, resp)				if total+uint64(resp.costTime) > MAX_UINT64 {					fmt.Println("too big")				}				total += uint64(resp.costTime)				// 已过测试时间				if time.Now().Second()-begin_time > runtime {					break				}			}		}()	}	wg.Wait()	// 统计	sort.Sort(respList)	all = len(respList)	cnt := int(float32(0.95) * float32(all))	return respList[all-cnt].costTime, float64(uint64(total) / uint64(all)), all}// ./main 测试次数 线程数func main() {	if len(os.Args) != 4 {		fmt.Println("invalid args, command: ./main 测试次数 测试时间 线程数 ")	} else {		pressureTimes, _ = strconv.Atoi(os.Args[1])		pressureDruation, _ = strconv.Atoi(os.Args[2])		goroutineCnt, _ = strconv.Atoi(os.Args[3])	}	for i := 0; i < pressureTimes; i++ {		resp, agv, total := Stress(goroutineCnt, pressureDruation)		fmt.Println(`总请求数:`, total, `95%响应时间:`, "ms", resp, `平均响应时间:`, agv, " ms")	}}-----------------------------------------------------------------------------
输出结果:

划线
评论
复制
发布于: 2020 年 07 月 22 日阅读数: 47
版权声明: 本文为 InfoQ 作者【GalaxyCreater】的原创文章。
原文链接:【http://xie.infoq.cn/article/2609790701a9454ad4980a473】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。

还未添加个人签名 2019.04.21 加入
还未添加个人简介











 
    
评论