Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customize bench #162

Merged
merged 3 commits into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ gout 是go写的http 客户端,为提高工作效率而开发
- [benchmarking a certain number of times](#benchmark-number)
- [benchmarking for a certain time](#benchmark-duration)
- [benchmarking at a fixed frequency](#benchmark-rate)
- [Custom benchmark functions](#Custom-benchmark-functions)
- [retry backoff](#retry-backoff)
- [import](#import)
- [send raw http request](#send-raw-http-request)
Expand Down Expand Up @@ -1269,6 +1270,45 @@ func main() {
}

```
### Custom benchmark functions
自定义压测函数,构造每次不一样的http request数据
```go
package main

import (
"fmt"
"github.com/google/uuid"
"github.com/guonaihong/gout"
"github.com/guonaihong/gout/filter"
"sync/atomic"
)

func main() {
i := int32(0)

err := filter.NewBench().
Concurrent(30). //开30个go程
Number(30000). //压测30000次
Loop(func(c *gout.Context) error {

// 下面的代码,每次生成不一样的http body 用于压测
uid := uuid.New() //生成uuid
id := atomic.AddInt32(&i, 1) //生成id, 可以理解为++i,线程安全版本

c.POST(":1234").SetJSON(gout.H{"sid": uid.String(),
"appkey": fmt.Sprintf("ak:%d", id),
"text": fmt.Sprintf("test text :%d", id)})
return nil

}).Do()

if err != nil {
fmt.Printf("err = %v\n", err)
}
}

```

## retry-backoff
retry 功能使用带抖动功能和指数的算法实现[backoff](http://www.awsarchitectureblog.com/2015/03/backoff.html)
```go
Expand Down
56 changes: 56 additions & 0 deletions _example/16e-customize-bench.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/guonaihong/gout"
"github.com/guonaihong/gout/filter"
"sync/atomic"
"time"
)

const (
benchNumber = 30000
benchConcurrent = 30
)

func server() {
router := gin.New()
router.POST("/", func(c *gin.Context) {
c.String(200, "hello world:gout")
})

router.Run()
}

func customize() {
i := int32(0)

err := filter.NewBench().
Concurrent(benchConcurrent).
Number(benchNumber).
Loop(func(c *gout.Context) error {

// 下面的代码,每次生成不一样的http body 用于压测
uid := uuid.New()
id := atomic.AddInt32(&i, 1)

c.POST(":8080").SetJSON(gout.H{"sid": uid.String(),
"appkey": fmt.Sprintf("ak:%d", id),
"text": fmt.Sprintf("test text :%d", id)})
return nil

}).Do()

if err != nil {
fmt.Printf("err = %v\n", err)
}
}

func main() {
go server()
time.Sleep(300 * time.Millisecond)

customize()
}
3 changes: 1 addition & 2 deletions _example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ module main

require (
github.com/gin-gonic/gin v1.4.1-0.20190924141841-9b9f4fab34cc
github.com/google/uuid v1.1.1
github.com/guonaihong/gout v0.0.6
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
)

go 1.13
43 changes: 25 additions & 18 deletions bench/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ type report struct {
type Report struct {
SendNum int // 已经发送的http 请求
report
Number int // 发送总次数
step int // 动态报表输出间隔
allResult chan result
waitQuit chan struct{} //等待startReport函数结束
allTimes []time.Duration
ctx context.Context
cancel func()
req *http.Request
Number int // 发送总次数
step int // 动态报表输出间隔
allResult chan result
waitQuit chan struct{} //等待startReport函数结束
allTimes []time.Duration
ctx context.Context
cancel func()
getRequest func() (*http.Request, error)

startTime time.Time
*http.Client
Expand All @@ -67,7 +67,14 @@ type Report struct {
}

// NewReport is a report initialization function
func NewReport(ctx context.Context, c, n int, duration time.Duration, req *http.Request, client *http.Client) *Report {
func NewReport(ctx context.Context,
c, n int,

duration time.Duration,

getRequest func() (*http.Request, error),

client *http.Client) *Report {
step := 0
if n > 150 {
if step = n / 10; step < 100 {
Expand All @@ -84,14 +91,14 @@ func NewReport(ctx context.Context, c, n int, duration time.Duration, req *http.
Duration: duration,
ErrMsg: make(map[string]int, 2),
},
waitQuit: make(chan struct{}),
Number: n,
step: step,
ctx: ctx,
cancel: cancel,
req: req,
Client: client,
startTime: time.Now(),
waitQuit: make(chan struct{}),
Number: n,
step: step,
ctx: ctx,
cancel: cancel,
getRequest: getRequest,
Client: client,
startTime: time.Now(),
}
}

Expand Down Expand Up @@ -129,7 +136,7 @@ func (r *Report) Process(work chan struct{}) {
for range work {
start := time.Now()

req, err := cloneRequest(r.req)
req, err := r.getRequest()
if err != nil {
r.addErrAndFailed(err)
continue
Expand Down
21 changes: 12 additions & 9 deletions bench/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ func Test_Bench_Report_number(t *testing.T) {

ctx := context.Background()

req, err := newRequest(ts.URL)
assert.NoError(t, err)
getRequest := func() (*http.Request, error) {
return newRequest(ts.URL)
}

p := NewReport(ctx, 1, number, time.Duration(0), req, http.DefaultClient)
p := NewReport(ctx, 1, number, time.Duration(0), getRequest, http.DefaultClient)

runReport(p, number)

Expand All @@ -77,10 +78,11 @@ func Test_Bench_Report_duration(t *testing.T) {

ctx := context.Background()

req, err := newRequest(ts.URL)
assert.NoError(t, err)
getRequest := func() (*http.Request, error) {
return newRequest(ts.URL)
}

p := NewReport(ctx, 1, 0, 300*time.Millisecond, req, http.DefaultClient)
p := NewReport(ctx, 1, 0, 300*time.Millisecond, getRequest, http.DefaultClient)

runReport(p, number)

Expand All @@ -93,10 +95,11 @@ func Test_Bench_Report_fail(t *testing.T) {

ctx := context.Background()

req, err := newRequest("fail")
assert.NoError(t, err)
getRequest := func() (*http.Request, error) {
return newRequest("fail url")
}

p := NewReport(ctx, 1, number, time.Duration(0), req, http.DefaultClient)
p := NewReport(ctx, 1, number, time.Duration(0), getRequest, http.DefaultClient)

runReport(p, number)

Expand Down
21 changes: 0 additions & 21 deletions bench/req.go

This file was deleted.

33 changes: 0 additions & 33 deletions bench/req_test.go

This file was deleted.

17 changes: 17 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"errors"
"net/http"
"reflect"
"unsafe"
)
Expand Down Expand Up @@ -63,3 +64,19 @@ func NewPtrVal(defValue interface{}) interface{} {
p.Elem().Set(reflect.ValueOf(defValue))
return p.Interface()
}

func CloneRequest(r *http.Request) (*http.Request, error) {
var err error

r0 := &http.Request{}
*r0 = *r

r0.Header = make(http.Header, len(r.Header))

for k, h := range r.Header {
r0.Header[k] = append([]string(nil), h...)
}

r0.Body, err = r.GetBody()
return r0, err
}
27 changes: 27 additions & 0 deletions core/core_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package core

import (
"bytes"
"github.com/stretchr/testify/assert"
"io"
"net/http"
"reflect"
"testing"
)
Expand Down Expand Up @@ -71,3 +74,27 @@ func Test_Core_NewPtrVal(t *testing.T) {
assert.Equal(t, val.Interface(), v.set)
}
}

func Test_Bench_closeRequest(t *testing.T) {
b := bytes.NewBuffer([]byte("hello"))
req, err := http.NewRequest("GET", "hello", b)
assert.NoError(t, err)

req.Header.Add("h1", "h2")
req.Header.Add("h2", "h2")

req2, err := CloneRequest(req)
assert.NoError(t, err)

// 测试http header是否一样
assert.Equal(t, req.Header, req2.Header)

b2, err := req2.GetBody()
assert.NoError(t, err)

b3 := bytes.NewBuffer(nil)
io.Copy(b3, b2)

// 测试body是否一样
assert.Equal(t, b, b3)
}
1 change: 1 addition & 0 deletions dataflow/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Bencher interface {
Number(n int) Bencher
Rate(rate int) Bencher
Durations(d time.Duration) Bencher
Loop(func(c *Context) error) Bencher
Do() error
}

Expand Down
Loading