架构学习第 7 周作业

用户头像
乐天
关注
发布于: 2020 年 07 月 22 日

以下两题,至少选做一题

  • 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?

吞吐量指单位时间内系统处理用户的请求数,系统吞吐量几个重要参数:QPS(TPS)、并发数、

响应时间

QPS(TPS)= 并发数/平均响应时间

性能压测的时候随着并发的增加,大致可以分成三个阶段

初期,性能测试,系统轻负载,并发数增加,响应时间比较短,吞吐量上升;

中期,负载测试,响应时间增加,吞吐量上升速度变慢,并逐渐饱和

后期,压力测试,响应时间变长,吞吐量不再上升,过负载有下降趋势



  • 用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。

package main

import (
"context"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"sync"
"time"
)

var concurrency int // -c
var timeout int // -t
var requests int // -n
var version string // -V
var url string // -l
var method string // -X
var data string // -d

func init() {
flag.IntVar(&concurrency, "c", 5, "concurrency per second")
flag.IntVar(&timeout, "t", 5, "timeout")
flag.IntVar(&requests, "n", 10, "total requests")
flag.StringVar(&version, "V", "1.0.0", "version")
flag.StringVar(&url, "l", "", "must specify a url")
flag.StringVar(&method, "X", "GET", "http method")
flag.StringVar(&data, "d", "", "specify post or put body data")
}

func parseFlag() {
flag.Parse()

if len(os.Args) < 2 || url == "" {
flag.Usage()
os.Exit(0)
}

if concurrency < 0 {
concurrency = 1
} else if (concurrency > requests) {
concurrency = requests
}

url = fixUrl(url)
}

func fixUrl(url string) string {
if strings.Contains(url, "http") {
return url
}
return "http://" + url
}

func handleHttpRequest(url string, pwg *sync.WaitGroup, tch chan<- int64, ctx context.Context, ctlch <-chan int64) {
for {
select {
case <-ctlch:
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
pwg.Done()
continue;
}
resp.Body.Close()
pwg.Done()
_, err = ioutil.ReadAll(resp.Body)
tch <- time.Now().UnixNano() / 1e6
case <-ctx.Done():
break;
}
}
}

func caculate(start int64, ends <-chan int64, total int) {
l := len(ends)
timeUse := make([]int64, 0, l)
var totalUse int64 = 0;
for i := 0; i < l; i++ {
x := <- ends
timeUse = append(timeUse, x - start)
totalUse += (x - start)
}

fmt.Printf("total %d request use time %d ms, success %d, fail %d\r\n", total, totalUse, l, total - l)
fmt.Printf("max cost %d ms\r\n", timeUse[l - 1])
fmt.Printf("min cost %d ms\r\n", timeUse[0])
fmt.Printf("95%% point cost %d ms\r\n", timeUse[int(l * 19 / 20)])
fmt.Printf("avg cost %d ms\r\n", totalUse / int64(l))
}

func main() {
parseFlag()
wg := sync.WaitGroup{}
wg.Add(requests);

tmCtx, cancelFunc := context.WithTimeout(context.Background(), time.Duration(5))
defer cancelFunc()

recvCh := make(chan int64, requests)
defer close(recvCh)

ctrlCh := make(chan int64, requests)
defer close(ctrlCh)

for i := 0; i < concurrency; i++ {
go handleHttpRequest(url, &wg, recvCh, tmCtx, ctrlCh)
}

start := time.Now().UnixNano() / 1e6
for i:= 0; i < requests; i++ {
ctrlCh <- int64(i)
}
wg.Wait()
caculate(start, recvCh, requests)
}





发布于: 2020 年 07 月 22 日 阅读数: 12
用户头像

乐天

关注

还未添加个人签名 2020.02.02 加入

还未添加个人简介

评论

发布
暂无评论
架构学习第7周作业