写点什么

架构师训练营第 0 期 - 第 7 周 - 命题作业

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

作业一:

以下两题,至少选做一题

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

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



第一题:

响应时间和吞吐量的变化,可用老师上课时的两张曲线图总结:

吞吐量变化曲线

响应时间

从上图可总结出响应时间和吞吐量的变化可以分为三个阶段:

  1. 性能测试(日常运行区间):系统负载远未达到系统承载能力上限时,随着并发压力的增加,响应时间几乎不上升,吞吐量随并发压力增加而线性增长、快速增加。

  2. 负载测试(介于系统最佳性能点与最大负载点之间):系统负载较高或接近饱和,随着并发压力的增加,响应时间明显变长,吞吐量增加速度放缓。

  3. 压力测试(高于最大负载点,直至系统崩溃点):系统负载已经或达到崩溃状态,随着并发压力的增加,响应时间不断增加甚至超时,吞吐量不再增加甚至因为崩溃而大幅降低。



第二题:

运行结果:



代码:

package main
import (
"flag"
"fmt"
"net/http"
"sort"
"sync"
"time"
"github.com/jiyu93/golog"
)
// FooTester 本次作业的压力测试工具
type FooTester struct {
TestURL string
Concurrent int
Total int
Results []int
count int
locker sync.RWMutex
}
// Run 运行测试
func (f *FooTester) Run() {
wg := sync.WaitGroup{}
for i := 0; i < f.Concurrent; i++ {
wg.Add(1)
go func() {
for {
f.locker.RLock()
if f.count >= f.Total {
f.locker.RUnlock()
wg.Done()
break
}
f.locker.RUnlock()
t := f.work(f.TestURL)
f.locker.Lock()
f.Results = append(f.Results, int(t))
f.count++
f.locker.Unlock()
}
}()
}
wg.Wait()
}
// work 执行单次测试并返回相应时间
func (f *FooTester) work(u string) int {
t1 := time.Now()
http.Get(u)
return int(time.Now().Sub(t1).Milliseconds())
}
// Print 输出结果
func (f *FooTester) Print() {
f.locker.RLock()
defer f.locker.RUnlock()
var sum, avg int
for _, v := range f.Results {
sum += v
}
avg = sum / len(f.Results)
sort.Ints(f.Results)
pos := int(float64(len(f.Results)) * 0.95)
fmt.Println("平均响应时间: ", avg, "ms")
fmt.Println("95%响应时间: ", f.Results[pos], "ms")
}
func main() {
testURL := flag.String("u", "", "测试URL")
cc := flag.Int("c", 0, "并发")
total := flag.Int("t", 0, "总请求次数")
flag.Parse()
if len(*testURL) == 0 || *cc <= 0 || *total <= 0 {
golog.Info("参数错误")
return
}
t := FooTester{
TestURL: *testURL,
Concurrent: *cc,
Total: *total,
Results: make([]int, 0),
}
t.Run()
t.Print()
}



用户头像

关注

还未添加个人签名 2018.09.10 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第 0 期 - 第 7 周 - 命题作业