- default config support for limt_access_speed.

* fix bug when request.Body is nil.
This commit is contained in:
gazebo
2018-10-27 12:29:27 +08:00
parent ecb04fbe72
commit 6a5afbb07f
5 changed files with 41 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ package ebaiapi
import "git.rosy.net.cn/baseapi/platformapi" import "git.rosy.net.cn/baseapi/platformapi"
var ( var (
apiLimitConfig = map[string]*platformapi.LimiterConfig{ apiLimitConfigs = map[string]*platformapi.LimiterConfig{
"sku.create": &platformapi.LimiterConfig{ "sku.create": &platformapi.LimiterConfig{
MaxAccessCount: 5 - 1, MaxAccessCount: 5 - 1,
TimeGapInSecond: 1, TimeGapInSecond: 1,
@@ -21,4 +21,9 @@ var (
TimeGapInSecond: 1, TimeGapInSecond: 1,
}, },
} }
defaultAPILimitConfig = &platformapi.LimiterConfig{
MaxAccessCount: 5 - 2,
TimeGapInSecond: 1,
}
) )

View File

@@ -52,7 +52,7 @@ func New(source, secret string, config ...*platformapi.APIConfig) *API {
secret: secret, secret: secret,
client: &http.Client{Timeout: curConfig.ClientTimeout}, client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig, config: &curConfig,
speedLimiter: platformapi.New(apiLimitConfig), speedLimiter: platformapi.New(apiLimitConfigs, defaultAPILimitConfig),
} }
return api return api
} }

View File

@@ -1,6 +1,7 @@
package platformapi package platformapi
import ( import (
"sync"
"time" "time"
"github.com/juju/ratelimit" "github.com/juju/ratelimit"
@@ -12,21 +13,38 @@ type LimiterConfig struct {
} }
type Limiter struct { type Limiter struct {
limitConfig map[string]*ratelimit.Bucket limitConfig map[string]*ratelimit.Bucket
defaultConfig *LimiterConfig
sync.RWMutex
} }
func New(config map[string]*LimiterConfig) *Limiter { func New(config map[string]*LimiterConfig, defaultConfig ...*LimiterConfig) *Limiter {
limiter := &Limiter{ limiter := &Limiter{
limitConfig: make(map[string]*ratelimit.Bucket), limitConfig: make(map[string]*ratelimit.Bucket),
} }
for k, v := range config { for k, v := range config {
limiter.limitConfig[k] = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapInSecond)*time.Second, int64(v.MaxAccessCount), int64(v.MaxAccessCount)) limiter.limitConfig[k] = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapInSecond)*time.Second, int64(v.MaxAccessCount), int64(v.MaxAccessCount))
} }
if len(defaultConfig) > 0 {
limiter.defaultConfig = defaultConfig[0]
}
return limiter return limiter
} }
func (l *Limiter) AccessAPI(apiName string) { func (l *Limiter) AccessAPI(apiName string) {
l.RLock()
bucket := l.limitConfig[apiName] bucket := l.limitConfig[apiName]
l.RUnlock()
if bucket == nil && l.defaultConfig != nil {
l.Lock()
if bucket = l.limitConfig[apiName]; bucket == nil {
v := l.defaultConfig
bucket = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapInSecond)*time.Second, int64(v.MaxAccessCount), int64(v.MaxAccessCount))
l.limitConfig[apiName] = bucket
}
l.Unlock()
}
if bucket != nil { if bucket != nil {
bucket.Wait(1) bucket.Wait(1)
} }

View File

@@ -18,6 +18,9 @@ func TestLimitSpeed(t *testing.T) {
MaxAccessCount: 10, MaxAccessCount: 10,
TimeGapInSecond: 10, TimeGapInSecond: 10,
}, },
}, &LimiterConfig{
MaxAccessCount: 1,
TimeGapInSecond: 2,
}) })
go func() { go func() {
@@ -36,5 +39,13 @@ func TestLimitSpeed(t *testing.T) {
count++ count++
} }
}() }()
go func() {
count := 0
for {
limiter.AccessAPI("otherAPI")
fmt.Printf("otherAPI, time:%s, count:%d\n", utils.GetCurTimeStr(), count)
count++
}
}()
time.Sleep(30 * time.Second) time.Sleep(30 * time.Second)
} }

View File

@@ -85,7 +85,9 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.
for { for {
savedBuf := new(bytes.Buffer) savedBuf := new(bytes.Buffer)
request := handleRequest() request := handleRequest()
request.Body = ioutil.NopCloser(io.TeeReader(request.Body, savedBuf)) if request.Body != nil {
request.Body = ioutil.NopCloser(io.TeeReader(request.Body, savedBuf))
}
response, err := client.Do(request) response, err := client.Do(request)
if err != nil { if err != nil {
baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry client.Get return err:%v", err) baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry client.Get return err:%v", err)