Skip to content

Commit

Permalink
Merge pull request #23 from andrewshan/main
Browse files Browse the repository at this point in the history
feat: support local config for ratelimit and add ratelimit demo
  • Loading branch information
andrewshan authored Dec 5, 2021
2 parents d010764 + d59f9ea commit 9fbe50f
Show file tree
Hide file tree
Showing 19 changed files with 652 additions and 388 deletions.
19 changes: 10 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
.DS_Store
.idea/
test_log/
backup/

polaris/log/*

angevil_test/
test/other/other_test_suit.go
.DS_Store
.idea/
test_log/
backup/

polaris/log/*

angevil_test/
test/other/other_test_suit.go
*.log
15 changes: 4 additions & 11 deletions pkg/config/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,6 @@ type RateLimitConfig interface {
IsEnable() bool
//设置是否启用限流能力
SetEnable(bool)
//返回限流行为使用的插件
//GetBehaviorPlugin(behavior RateLimitBehavior) string
//设置限流行为使用的插件
//SetBehaviorPlugin(behavior RateLimitBehavior, p string)
SetMode(string)

GetMode() model.ConfigMode

SetRateLimitCluster(namespace string, service string)

GetRateLimitCluster() ServerClusterConfig
//获取最大限流窗口数量
GetMaxWindowSize() int
//设置最大限流窗口数量
Expand All @@ -95,6 +84,10 @@ type RateLimitConfig interface {
GetPurgeInterval() time.Duration
//设置超时淘汰周期
SetPurgeInterval(time.Duration)
// GetRules
GetRules() []RateLimitRule
// SetRules
SetRules([]RateLimitRule)
}

//系统配置信息
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/circuitbreaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type CircuitBreakerConfigImpl struct {
//熔断器定时检查周期
CheckPeriod *time.Duration `yaml:"checkPeriod" json:"checkPeriod"`
//熔断插件链
Chain []string `yaml:"chain"`
Chain []string `yaml:"chain" json:"chain"`
//熔断周期,被熔断后多久可以变为半开
SleepWindow *time.Duration `yaml:"sleepWindow" json:"sleepWindow"`
//半开状态后最多分配多少个探测请求
Expand Down
108 changes: 66 additions & 42 deletions pkg/config/ratelimiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ package config
import (
"errors"
"fmt"
"github.com/polarismesh/polaris-go/pkg/model"
"github.com/polarismesh/polaris-go/pkg/plugin/common"
"strconv"
"strings"
"time"
)

Expand All @@ -32,14 +31,59 @@ type RateLimitConfigImpl struct {
Enable *bool `yaml:"enable" json:"enable"`
//各个限流插件的配置
Plugin PluginConfigs `yaml:"plugin" json:"plugin"`
// mode 0: local 1: global
Mode string `yaml:"mode" json:"mode"`
// rateLimitCluster
RateLimitCluster *ServerClusterConfigImpl `yaml:"rateLimitCluster" json:"rateLimitCluster"`
//最大限流窗口数量
MaxWindowSize int `yaml:"maxWindowSize" json:"maxWindowSize"`
//超时window检查周期
PurgeInterval time.Duration `yaml:"purgeInterval" json:"purgeInterval"`
//本地限流规则
Rules []RateLimitRule `yaml:"rules"`
}

// RateLimitRule 限流规则
type RateLimitRule struct {
Namespace string `yaml:"namespace"`
Service string `yaml:"service"`
Labels map[string]Matcher `yaml:"labels"`
MaxAmount int `yaml:"maxAmount"`
ValidDuration time.Duration `yaml:"validDuration"`
}

// Verify 校验限流规则
func (r *RateLimitRule) Verify() error {
if len(r.Namespace) == 0 {
return errors.New("namespace is empty")
}
if len(r.Service) == 0 {
return errors.New("service is empty")
}
if len(r.Labels) > 0 {
for _, matcher := range r.Labels {
if len(matcher.Type) > 0 {
upperType := strings.ToUpper(matcher.Type)
if upperType != TypeExact && upperType != TypeRegex {
return errors.New(fmt.Sprintf("matcher.type should be %s or %s", TypeExact, TypeRegex))
}
}
}
}
if r.ValidDuration < time.Second {
return errors.New("validDuration must greater than or equals to 1s")
}
if r.MaxAmount < 0 {
return errors.New("maxAmount must greater than or equals to 0")
}
return nil
}

const (
TypeExact = "EXACT"
TypeRegex = "REGEX"
)

// Matcher 标签匹配类型
type Matcher struct {
Type string `yaml:"type"`
Value string `yaml:"value"`
}

//是否启用限流能力
Expand All @@ -63,10 +107,11 @@ func (r *RateLimitConfigImpl) Verify() error {
if nil == r.Enable {
return fmt.Errorf("provider.rateLimit.enable must not be nil")
}
if r.RateLimitCluster != nil {
if r.RateLimitCluster.GetNamespace() == ServerNamespace &&
r.RateLimitCluster.GetService() == ForbidServerMetricService {
return errors.New("RateLimitCluster can not set to polaris.metric")
if len(r.Rules) > 0 {
for _, rule := range r.Rules {
if err := rule.Verify(); nil != err {
return err
}
}
}
return r.Plugin.Verify()
Expand All @@ -93,49 +138,18 @@ func (r *RateLimitConfigImpl) SetDefault() {
r.PurgeInterval = DefaultRateLimitPurgeInterval
}
r.Plugin.SetDefault(common.TypeRateLimiter)
r.RateLimitCluster.SetDefault()
}

//设置插件配置
func (r *RateLimitConfigImpl) SetPluginConfig(pluginName string, value BaseConfig) error {
return r.Plugin.SetPluginConfig(common.TypeRateLimiter, pluginName, value)
}

func (r *RateLimitConfigImpl) SetMode(mode string) {
r.Mode = mode
}

func (r *RateLimitConfigImpl) GetMode() model.ConfigMode {
if r.Mode == model.RateLimitLocal {
return model.ConfigQuotaLocalMode
} else if r.Mode == model.RateLimitGlobal {
return model.ConfigQuotaGlobalMode
} else {
return model.ConfigQuotaLocalMode
}
}

func (r *RateLimitConfigImpl) SetRateLimitCluster(namespace string, service string) {
if r.RateLimitCluster == nil {
r.RateLimitCluster = &ServerClusterConfigImpl{}
}
r.RateLimitCluster.SetNamespace(namespace)
r.RateLimitCluster.SetService(service)
}

func (r *RateLimitConfigImpl) GetRateLimitCluster() ServerClusterConfig {
return r.RateLimitCluster
}

//配置初始化
func (r *RateLimitConfigImpl) Init() {
r.Rules = []RateLimitRule{}
r.Plugin = PluginConfigs{}
r.Plugin.Init(common.TypeRateLimiter)
r.Mode = strconv.Itoa(int(model.ConfigQuotaGlobalMode))
r.RateLimitCluster = &ServerClusterConfigImpl{
Namespace: "",
Service: "",
}
}

//GetMaxWindowSize
Expand All @@ -157,3 +171,13 @@ func (r *RateLimitConfigImpl) GetPurgeInterval() time.Duration {
func (r *RateLimitConfigImpl) SetPurgeInterval(v time.Duration) {
r.PurgeInterval = v
}

// GetRules
func (r *RateLimitConfigImpl) GetRules() []RateLimitRule {
return r.Rules
}

// GetRules
func (r *RateLimitConfigImpl) SetRules(rules []RateLimitRule) {
r.Rules = rules
}
Loading

0 comments on commit 9fbe50f

Please sign in to comment.