131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
package http
|
|
|
|
import (
|
|
"hash/crc32"
|
|
"math/rand"
|
|
"strconv"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"go-common/library/log"
|
|
bm "go-common/library/net/http/blademaster"
|
|
"go-common/library/rate"
|
|
"go-common/library/rate/limit"
|
|
"go-common/library/rate/limit/bench/stress/conf"
|
|
"go-common/library/rate/limit/bench/stress/service"
|
|
"go-common/library/rate/vegas"
|
|
)
|
|
|
|
var (
|
|
svc *service.Service
|
|
req int64
|
|
qps int64
|
|
)
|
|
|
|
// Init init
|
|
func Init(c *conf.Config) {
|
|
rand.Seed(time.Now().Unix())
|
|
initService(c)
|
|
// init router
|
|
engineInner := bm.DefaultServer(c.BM.Inner)
|
|
outerRouter(engineInner)
|
|
if err := engineInner.Start(); err != nil {
|
|
log.Error("xhttp.Serve error(%v)", err)
|
|
panic(err)
|
|
}
|
|
engineLocal := bm.DefaultServer(c.BM.Local)
|
|
localRouter(engineLocal)
|
|
if err := engineLocal.Start(); err != nil {
|
|
log.Error("xhttp.Serve error(%v)", err)
|
|
panic(err)
|
|
}
|
|
if log.V(1) {
|
|
go calcuQPS()
|
|
}
|
|
}
|
|
|
|
// initService init services.
|
|
func initService(c *conf.Config) {
|
|
// idfSvc = identify.New(c.Identify)
|
|
svc = service.New(c)
|
|
}
|
|
|
|
// outerRouter init outer router api path.
|
|
func outerRouter(e *bm.Engine) {
|
|
v := vegas.New()
|
|
go func() {
|
|
ticker := time.NewTicker(time.Second * 3)
|
|
defer ticker.Stop()
|
|
for {
|
|
<-ticker.C
|
|
m := v.Stat()
|
|
log.Info("vegas: limit(%d) inFlight(%d) minRtt(%v) rtt(%v)", m.Limit, m.InFlight, m.MinRTT, m.LastRTT)
|
|
}
|
|
}()
|
|
l := limit.New(nil)
|
|
//init api
|
|
e.GET("/monitor/ping", ping)
|
|
group := e.Group("/stress")
|
|
group.GET("/normal", aqmTest)
|
|
group.GET("/vegas", func(c *bm.Context) {
|
|
start := time.Now()
|
|
done, success := v.Acquire()
|
|
if !success {
|
|
done(time.Time{}, rate.Ignore)
|
|
c.AbortWithStatus(509)
|
|
return
|
|
}
|
|
defer done(start, rate.Success)
|
|
c.Next()
|
|
}, aqmTest)
|
|
group.GET("/attack", func(c *bm.Context) {
|
|
done, err := l.Allow(c)
|
|
defer done(rate.Success)
|
|
if err != nil {
|
|
c.AbortWithStatus(509)
|
|
return
|
|
}
|
|
c.Next()
|
|
}, aqmTest)
|
|
|
|
}
|
|
|
|
func calcuQPS() {
|
|
var creq, breq int64
|
|
for {
|
|
time.Sleep(time.Second * 5)
|
|
creq = atomic.LoadInt64(&req)
|
|
delta := creq - breq
|
|
atomic.StoreInt64(&qps, delta/5)
|
|
breq = creq
|
|
log.Info("HTTP QPS:%d", atomic.LoadInt64(&qps))
|
|
}
|
|
|
|
}
|
|
func aqmTest(c *bm.Context) {
|
|
params := c.Request.Form
|
|
sleep, err := strconv.ParseInt(params.Get("sleep"), 10, 64)
|
|
if err == nil {
|
|
time.Sleep(time.Millisecond * time.Duration(sleep))
|
|
}
|
|
atomic.AddInt64(&req, 1)
|
|
for i := 0; i < 3000+rand.Intn(3000); i++ {
|
|
crc32.Checksum([]byte(`testasdwfwfsddsfgwddcscsc
|
|
http://git.bilibili.co/platform/go-common/merge_requests/new?merge_request%5Bsource_branch%5D=stress%2Fcodel`), crc32.IEEETable)
|
|
}
|
|
}
|
|
|
|
// ping check server ok.
|
|
func ping(c *bm.Context) {
|
|
}
|
|
|
|
// innerRouter init local router api path.
|
|
func localRouter(e *bm.Engine) {
|
|
//init api
|
|
e.GET("/monitor/ping", ping)
|
|
group := e.Group("/x/main/stress")
|
|
{
|
|
group.GET("", aqmTest)
|
|
}
|
|
}
|