Files
2019-04-22 18:49:16 +08:00

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)
}
}