diff --git a/platformapi/ebaiapi/access_limit.go b/platformapi/ebaiapi/access_limit.go index 31c5915d..d8dad872 100644 --- a/platformapi/ebaiapi/access_limit.go +++ b/platformapi/ebaiapi/access_limit.go @@ -8,34 +8,82 @@ const ( var ( apiLimitConfigs = map[string]*platformapi.LimiterConfig{ - allAPI: &platformapi.LimiterConfig{ - MaxAccessCount: 5, + // allAPI: &platformapi.LimiterConfig{ + // MaxAccessCount: 5, + // TimeGapMilliSecond: 1000, + // }, + "sku.shop.category.update": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.shop.category.delete": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, TimeGapMilliSecond: 1000, }, "sku.create": &platformapi.LimiterConfig{ MaxAccessCount: 5 - 1, TimeGapMilliSecond: 1000, }, - "sku.delete": &platformapi.LimiterConfig{ + "sku.online": &platformapi.LimiterConfig{ MaxAccessCount: 1, - TimeGapMilliSecond: 2000, + TimeGapMilliSecond: 1000 + 200, }, - "sku.shop.category.delete": &platformapi.LimiterConfig{ - MaxAccessCount: 1, + "sku.online.one": &platformapi.LimiterConfig{ + MaxAccessCount: 10 - 1, TimeGapMilliSecond: 1000, }, - "sku.shop.category.create": &platformapi.LimiterConfig{ - MaxAccessCount: 2, + "sku.offline": &platformapi.LimiterConfig{ + MaxAccessCount: 1, + TimeGapMilliSecond: 1000 + 200, + }, + "sku.offline.one": &platformapi.LimiterConfig{ + MaxAccessCount: 10 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.update": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, TimeGapMilliSecond: 1000, }, "sku.list": &platformapi.LimiterConfig{ - MaxAccessCount: 5 - 3, + MaxAccessCount: 5 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.price.update.batch": &platformapi.LimiterConfig{ + MaxAccessCount: 1, + TimeGapMilliSecond: 1000 + 200, + }, + "sku.stock.update.batch": &platformapi.LimiterConfig{ + MaxAccessCount: 2, + TimeGapMilliSecond: 1000 + 200, + }, + "sku.delete": &platformapi.LimiterConfig{ + MaxAccessCount: 1, + TimeGapMilliSecond: 1000 + 200, + }, + "sku.shop.category.create": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.shop.category.map": &platformapi.LimiterConfig{ + MaxAccessCount: 10 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.category.list": &platformapi.LimiterConfig{ + MaxAccessCount: 1, + TimeGapMilliSecond: 1000 + 200, + }, + "sku.brand.list": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, + TimeGapMilliSecond: 1000, + }, + "sku.shop.category.get": &platformapi.LimiterConfig{ + MaxAccessCount: 5 - 1, TimeGapMilliSecond: 1000, }, } - defaultAPILimitConfig = &platformapi.LimiterConfig{ - MaxAccessCount: 5 - 2, - TimeGapMilliSecond: 1000, - } + // defaultAPILimitConfig = &platformapi.LimiterConfig{ + // MaxAccessCount: 5 - 1, + // TimeGapMilliSecond: 1000, + // } ) diff --git a/platformapi/ebaiapi/ebaiapi.go b/platformapi/ebaiapi/ebaiapi.go index 18b17e13..3d233c91 100644 --- a/platformapi/ebaiapi/ebaiapi.go +++ b/platformapi/ebaiapi/ebaiapi.go @@ -63,7 +63,7 @@ func New(source, secret string, config ...*platformapi.APIConfig) *API { secret: secret, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, - speedLimiter: platformapi.New(apiLimitConfigs, defaultAPILimitConfig), + speedLimiter: platformapi.New(apiLimitConfigs, nil), //defaultAPILimitConfig), storeCookies: make(map[string]string), } return api @@ -96,7 +96,7 @@ func (a *API) getShopID(body map[string]interface{}) (shopID string) { func (a *API) AccessAPI(cmd string, body map[string]interface{}) (retVal *ResponseResult, err error) { baseapi.SugarLogger.Debugf("ebai AccessAPI cmd:%s", cmd) // a.speedLimiter.AccessAPI(allAPI) - a.speedLimiter.AccessAPI(cmd) + a.speedLimiter.AccessAPI(cmd, a.getShopID(body)) if body == nil { body = make(map[string]interface{}, 0) } diff --git a/platformapi/limit_access_speed.go b/platformapi/limit_access_speed.go index 5bf61d0a..6e907a19 100644 --- a/platformapi/limit_access_speed.go +++ b/platformapi/limit_access_speed.go @@ -1,6 +1,7 @@ package platformapi import ( + "math" "sync" "time" @@ -13,36 +14,45 @@ type LimiterConfig struct { } type Limiter struct { - limitConfig map[string]*ratelimit.Bucket - defaultConfig *LimiterConfig + limitBucketMap map[string]*ratelimit.Bucket + limitConfigMap map[string]*LimiterConfig + defaultConfig *LimiterConfig sync.RWMutex } func New(config map[string]*LimiterConfig, defaultConfig ...*LimiterConfig) *Limiter { limiter := &Limiter{ - limitConfig: make(map[string]*ratelimit.Bucket), - } - for k, v := range config { - limiter.limitConfig[k] = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapMilliSecond)*time.Millisecond, int64(v.MaxAccessCount), int64(v.MaxAccessCount)) + limitConfigMap: config, + limitBucketMap: make(map[string]*ratelimit.Bucket), } + // for k, v := range config { + // limiter.limitBucketMap[k] = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapMilliSecond)*time.Millisecond, int64(v.MaxAccessCount), int64(v.MaxAccessCount)) + // } if len(defaultConfig) > 0 { limiter.defaultConfig = defaultConfig[0] } return limiter } -func (l *Limiter) AccessAPI(apiName string) { +func (l *Limiter) AccessAPI(apiName, shopID string) { + bucketKey := shopID + "." + apiName l.RLock() - bucket := l.limitConfig[apiName] + bucket := l.limitBucketMap[bucketKey] l.RUnlock() - if bucket == nil && l.defaultConfig != nil { + if bucket == nil { l.Lock() - if bucket = l.limitConfig[apiName]; bucket == nil { - if v := l.defaultConfig; v != nil { - bucket = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapMilliSecond)*time.Millisecond, int64(v.MaxAccessCount), int64(v.MaxAccessCount)) - l.limitConfig[apiName] = bucket + if bucket = l.limitBucketMap[bucketKey]; bucket == nil { + v := l.limitConfigMap[apiName] + if v == nil { + v = l.defaultConfig } + if v != nil { + bucket = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapMilliSecond)*time.Millisecond, int64(v.MaxAccessCount), int64(v.MaxAccessCount)) + } else { + bucket = ratelimit.NewBucket(time.Second, math.MaxInt64) // 占位用 + } + l.limitBucketMap[bucketKey] = bucket } l.Unlock() } diff --git a/platformapi/limit_access_speed_test.go b/platformapi/limit_access_speed_test.go index 284107d5..c0c5b024 100644 --- a/platformapi/limit_access_speed_test.go +++ b/platformapi/limit_access_speed_test.go @@ -26,7 +26,7 @@ func TestLimitSpeed(t *testing.T) { utils.CallFuncAsync(func() { count := 0 for { - limiter.AccessAPI("limited1persecond") + limiter.AccessAPI("limited1persecond", "") fmt.Printf("limited1persecond, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count) count++ } @@ -34,7 +34,7 @@ func TestLimitSpeed(t *testing.T) { utils.CallFuncAsync(func() { count := 0 for { - limiter.AccessAPI("limited10per10second") + limiter.AccessAPI("limited10per10second", "") fmt.Printf("limited10per10second, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count) count++ } @@ -42,7 +42,7 @@ func TestLimitSpeed(t *testing.T) { utils.CallFuncAsync(func() { count := 0 for { - limiter.AccessAPI("otherAPI") + limiter.AccessAPI("otherAPI", "") fmt.Printf("otherAPI, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count) count++ }