- ebai限访问频率按门店来
This commit is contained in:
@@ -8,34 +8,82 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
apiLimitConfigs = map[string]*platformapi.LimiterConfig{
|
apiLimitConfigs = map[string]*platformapi.LimiterConfig{
|
||||||
allAPI: &platformapi.LimiterConfig{
|
// allAPI: &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 5,
|
// 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,
|
TimeGapMilliSecond: 1000,
|
||||||
},
|
},
|
||||||
"sku.create": &platformapi.LimiterConfig{
|
"sku.create": &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 5 - 1,
|
MaxAccessCount: 5 - 1,
|
||||||
TimeGapMilliSecond: 1000,
|
TimeGapMilliSecond: 1000,
|
||||||
},
|
},
|
||||||
"sku.delete": &platformapi.LimiterConfig{
|
"sku.online": &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 1,
|
MaxAccessCount: 1,
|
||||||
TimeGapMilliSecond: 2000,
|
TimeGapMilliSecond: 1000 + 200,
|
||||||
},
|
},
|
||||||
"sku.shop.category.delete": &platformapi.LimiterConfig{
|
"sku.online.one": &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 1,
|
MaxAccessCount: 10 - 1,
|
||||||
TimeGapMilliSecond: 1000,
|
TimeGapMilliSecond: 1000,
|
||||||
},
|
},
|
||||||
"sku.shop.category.create": &platformapi.LimiterConfig{
|
"sku.offline": &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 2,
|
MaxAccessCount: 1,
|
||||||
|
TimeGapMilliSecond: 1000 + 200,
|
||||||
|
},
|
||||||
|
"sku.offline.one": &platformapi.LimiterConfig{
|
||||||
|
MaxAccessCount: 10 - 1,
|
||||||
|
TimeGapMilliSecond: 1000,
|
||||||
|
},
|
||||||
|
"sku.update": &platformapi.LimiterConfig{
|
||||||
|
MaxAccessCount: 5 - 1,
|
||||||
TimeGapMilliSecond: 1000,
|
TimeGapMilliSecond: 1000,
|
||||||
},
|
},
|
||||||
"sku.list": &platformapi.LimiterConfig{
|
"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,
|
TimeGapMilliSecond: 1000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultAPILimitConfig = &platformapi.LimiterConfig{
|
// defaultAPILimitConfig = &platformapi.LimiterConfig{
|
||||||
MaxAccessCount: 5 - 2,
|
// MaxAccessCount: 5 - 1,
|
||||||
TimeGapMilliSecond: 1000,
|
// TimeGapMilliSecond: 1000,
|
||||||
}
|
// }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -63,7 +63,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(apiLimitConfigs, defaultAPILimitConfig),
|
speedLimiter: platformapi.New(apiLimitConfigs, nil), //defaultAPILimitConfig),
|
||||||
storeCookies: make(map[string]string),
|
storeCookies: make(map[string]string),
|
||||||
}
|
}
|
||||||
return api
|
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) {
|
func (a *API) AccessAPI(cmd string, body map[string]interface{}) (retVal *ResponseResult, err error) {
|
||||||
baseapi.SugarLogger.Debugf("ebai AccessAPI cmd:%s", cmd)
|
baseapi.SugarLogger.Debugf("ebai AccessAPI cmd:%s", cmd)
|
||||||
// a.speedLimiter.AccessAPI(allAPI)
|
// a.speedLimiter.AccessAPI(allAPI)
|
||||||
a.speedLimiter.AccessAPI(cmd)
|
a.speedLimiter.AccessAPI(cmd, a.getShopID(body))
|
||||||
if body == nil {
|
if body == nil {
|
||||||
body = make(map[string]interface{}, 0)
|
body = make(map[string]interface{}, 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package platformapi
|
package platformapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -13,36 +14,45 @@ type LimiterConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Limiter struct {
|
type Limiter struct {
|
||||||
limitConfig map[string]*ratelimit.Bucket
|
limitBucketMap map[string]*ratelimit.Bucket
|
||||||
defaultConfig *LimiterConfig
|
limitConfigMap map[string]*LimiterConfig
|
||||||
|
defaultConfig *LimiterConfig
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config map[string]*LimiterConfig, defaultConfig ...*LimiterConfig) *Limiter {
|
func New(config map[string]*LimiterConfig, defaultConfig ...*LimiterConfig) *Limiter {
|
||||||
limiter := &Limiter{
|
limiter := &Limiter{
|
||||||
limitConfig: make(map[string]*ratelimit.Bucket),
|
limitConfigMap: config,
|
||||||
}
|
limitBucketMap: 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))
|
|
||||||
}
|
}
|
||||||
|
// 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 {
|
if len(defaultConfig) > 0 {
|
||||||
limiter.defaultConfig = defaultConfig[0]
|
limiter.defaultConfig = defaultConfig[0]
|
||||||
}
|
}
|
||||||
return limiter
|
return limiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Limiter) AccessAPI(apiName string) {
|
func (l *Limiter) AccessAPI(apiName, shopID string) {
|
||||||
|
bucketKey := shopID + "." + apiName
|
||||||
l.RLock()
|
l.RLock()
|
||||||
bucket := l.limitConfig[apiName]
|
bucket := l.limitBucketMap[bucketKey]
|
||||||
l.RUnlock()
|
l.RUnlock()
|
||||||
|
|
||||||
if bucket == nil && l.defaultConfig != nil {
|
if bucket == nil {
|
||||||
l.Lock()
|
l.Lock()
|
||||||
if bucket = l.limitConfig[apiName]; bucket == nil {
|
if bucket = l.limitBucketMap[bucketKey]; bucket == nil {
|
||||||
if v := l.defaultConfig; v != nil {
|
v := l.limitConfigMap[apiName]
|
||||||
bucket = ratelimit.NewBucketWithQuantum(time.Duration(v.TimeGapMilliSecond)*time.Millisecond, int64(v.MaxAccessCount), int64(v.MaxAccessCount))
|
if v == nil {
|
||||||
l.limitConfig[apiName] = bucket
|
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()
|
l.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func TestLimitSpeed(t *testing.T) {
|
|||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
count := 0
|
count := 0
|
||||||
for {
|
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)
|
fmt.Printf("limited1persecond, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count)
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ func TestLimitSpeed(t *testing.T) {
|
|||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
count := 0
|
count := 0
|
||||||
for {
|
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)
|
fmt.Printf("limited10per10second, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count)
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func TestLimitSpeed(t *testing.T) {
|
|||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
count := 0
|
count := 0
|
||||||
for {
|
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)
|
fmt.Printf("otherAPI, time:%s, count:%d\n", time.Now().Format("2006-01-02 15:04:05.00000"), count)
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user