Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rate limit filter #169

Merged
merged 45 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
848409d
update dubbo-go to v1.5.6 & fmt sth.
mark4z Apr 15, 2021
8133665
fix fmt
mark4z Apr 15, 2021
980669a
Merge branch 'develop' into update_dubbo
mark4z Apr 21, 2021
67d98da
Update go.mod
mark4z Apr 22, 2021
f3f2437
update dubbo-go to v1.5.6 & fmt sth.
mark4z Apr 22, 2021
44543c4
update dubbo-go to v1.5.6 & fmt sth.
mark4z Apr 15, 2021
bca62b8
fix fmt
mark4z Apr 15, 2021
0547c78
Merge branch 'develop' into update_dubbo
mark4z Apr 28, 2021
af4a56f
rateLimit filter
mark4z Mar 19, 2021
9b99a24
add licence header
mark4z May 17, 2021
c865a5d
fix imports
mark4z May 17, 2021
2e35f60
add license header
mark4z May 17, 2021
564a2d3
add license header
mark4z May 17, 2021
be02472
Merge branch 'develop' into ratelimit
kezhenxu94 May 17, 2021
2563b4d
fix ci
mark4z May 17, 2021
93363b7
Merge remote-tracking branch 'origin/ratelimit' into ratelimit
mark4z May 17, 2021
90836a4
Merge branch 'develop' into ratelimit
mark4z May 18, 2021
da69b51
fix matcher var inline
mark4z May 18, 2021
49015e4
Merge remote-tracking branch 'origin/ratelimit' into ratelimit
mark4z May 18, 2021
2dd2b8e
Merge branch 'develop' into update_dubbo
mark4z May 18, 2021
172ad82
fix ci
mark4z May 18, 2021
c73a7d0
fix sync.RWMutex
mark4z May 18, 2021
153e99c
errors.warp
mark4z May 18, 2021
02cb291
test table
mark4z May 18, 2021
15a66ed
remove unreachable statement
mark4z May 19, 2021
b9a7c17
Pattern pattern,omitempty
mark4z May 21, 2021
b435753
Merge branch 'develop' of https://github.com/apache/dubbo-go-pixiu in…
mark4z May 23, 2021
8a6dae2
update develop
mark4z May 23, 2021
79d0c3b
update the docs for ratelimit
mark4z May 28, 2021
602f8b2
update develop
mark4z May 29, 2021
c3a7da5
ratelimit filter
mark4z Jun 6, 2021
b93e6b1
ratelimit filter
mark4z Jun 6, 2021
5ef9f3a
ratelimit filter
mark4z Jun 6, 2021
f0e7b70
Merge branch 'develop' into update_dubbo
mark4z Jun 10, 2021
ee45a7b
ratelimit filter
mark4z Jun 10, 2021
bb18bb0
ratelimit filter
mark4z Jun 11, 2021
fd1abef
ratelimit filter
mark4z Jun 11, 2021
5f9e8ca
ratelimit filter
mark4z Jun 12, 2021
10d44e8
ratelimit filter
mark4z Jun 13, 2021
5d24779
Merge branch 'update_dubbo' into ratelimit
mark4z Jun 13, 2021
a4597ab
ratelimit filter
mark4z Jun 13, 2021
a482ff4
ratelimit filter
mark4z Jun 13, 2021
5429895
ratelimit filter
mark4z Jun 13, 2021
8af536e
ratelimit filter
mark4z Jun 13, 2021
33e3246
Merge branch 'develop' of https://github.com/apache/dubbo-go-pixiu in…
mark4z Jun 24, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion configs/api_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,34 @@ pluginsGroup:
- name: "trace"
version: "0.0.1"
priority: 1000
externalLookupName: "ExternalPluginTrace"
externalLookupName: "ExternalPluginTrace"
rateLimit:
resources:
- name: test-dubbo
items:
#Exact
- matchStrategy: 0
pattern: "/api/v1/test-dubbo/user"
#Regex
- matchStrategy: 1
pattern: "/api/v1/test-dubbo/user/*"
- name: test-http
items:
#Exact
- matchStrategy: 0
pattern: "/api/v1/http/foo"
- matchStrategy: 0
pattern: "/api/v1/http/bar"
#Regex
- matchStrategy: 1
pattern: "/api/v1/http/foo/*"
- matchStrategy: 1
pattern: "/api/v1/http/bar/*"

rules:
#qps sample At most 100 requests can be passed in 1000ms, so qps is 100
- resource: "test-dubbo"
enable: true
flowRule:
threshold: 100
statintervalinms: 1000
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* [dubbo](sample/dubbo.md)
* [http](sample/http.md)
* [mock](sample/mock.md)
* [plugins](../samples/plugins/index.md)

## [User Guide](user/README.md)

Expand Down
19 changes: 12 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ module github.com/apache/dubbo-go-pixiu
go 1.14

require (
github.com/apache/dubbo-go v1.5.5
github.com/apache/dubbo-go-hessian2 v1.7.0
github.com/alibaba/sentinel-golang v1.0.2
github.com/apache/dubbo-go v1.5.7-rc1
github.com/apache/dubbo-go-hessian2 v1.9.2
github.com/coreos/etcd v3.3.25+incompatible
github.com/dubbogo/dubbo-go-pixiu-filter v0.1.4-0.20210427062645-0bec837d429e
github.com/dubbogo/go-zookeeper v1.0.2
github.com/dubbogo/dubbo-go-pixiu-filter v0.1.4-0.20210613012702-8488bf80772c
github.com/dubbogo/go-zookeeper v1.0.3
github.com/dubbogo/gost v1.11.7
github.com/emirpasic/gods v1.12.0
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/goinggo/mapstructure v0.0.0-20140717182941-194205d9b4a9
github.com/hashicorp/consul/api v1.5.0
github.com/pkg/errors v0.9.1
github.com/shirou/gopsutil v3.21.3+incompatible // indirect
github.com/spf13/cast v1.3.1
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.0
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/urfave/cli v1.22.4
go.uber.org/zap v1.16.0
google.golang.org/grpc v1.26.0
google.golang.org/grpc v1.33.1
gopkg.in/yaml.v2 v2.4.0
)

replace github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 => github.com/envoyproxy/go-control-plane v0.8.0
replace (
github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.8.0
google.golang.org/grpc v1.33.1 => google.golang.org/grpc v1.26.0
)
390 changes: 113 additions & 277 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/common/constant/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
RecoveryFilter = "dgp.filters.recovery"
ResponseFilter = "dgp.filters.response"
AccessLogFilter = "dgp.filters.access_log"
RateLimitFilter = "dgp.filters.rate_limit"
)

const (
Expand Down
5 changes: 5 additions & 0 deletions pkg/filter/plugins/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ var (
errEmptyPluginConfig = errors.New("Empty plugin config")
)

func Init(groups []config.PluginsGroup, filePath string, resources []config.Resource) {
InitPluginsGroup(groups, filePath)
InitAPIURLWithFilterChain(resources)
}

// FilterChain include Pre & Post filters
type FilterChain struct {
Pre context.FilterChain
Expand Down
74 changes: 74 additions & 0 deletions pkg/filter/ratelimit/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ratelimit

import (
sentinel "github.com/alibaba/sentinel-golang/api"
sc "github.com/alibaba/sentinel-golang/core/config"
"github.com/alibaba/sentinel-golang/core/flow"
"github.com/alibaba/sentinel-golang/logging"
"github.com/dubbogo/dubbo-go-pixiu-filter/pkg/api/config/ratelimit"
"github.com/pkg/errors"
)

import (
"github.com/apache/dubbo-go-pixiu/pkg/filter/ratelimit/matcher"
"github.com/apache/dubbo-go-pixiu/pkg/logger"
)

func rateLimitInit(c *ratelimit.Config) error {
sentinelConf := sc.NewDefaultConfig()
if len(c.LogPath) > 0 {
sentinelConf.Sentinel.Log.Dir = c.LogPath
}
_ = logging.ResetGlobalLogger(getWrappedLogger())

if err := sentinel.InitWithConfig(sentinelConf); err != nil {
return errors.Wrap(err, "rate limit init fail")
}
matcher.Init()

loadApiResources(c.Resources)
loadRules(c.Rules)
return nil
}

// OnUpdate update api & rule
func OnUpdate(c ratelimit.Config) {
loadApiResources(c.Resources)
loadRules(c.Rules)
}

// loadRules
func loadRules(rules []ratelimit.Rule) {
var enableRules []*flow.Rule
for _, v := range rules {
if v.Enable {
enableRules = append(enableRules, &v.FlowRule)
}
}

if _, err := flow.LoadRules(enableRules); err != nil {
logger.Warnf("rate limit load rules err: %v", err)
}
}

// loadApiResources
func loadApiResources(apis []ratelimit.Resource) {
matcher.Load(apis)
}
33 changes: 33 additions & 0 deletions pkg/filter/ratelimit/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ratelimit

import "testing"

func TestInit(t *testing.T) {
c := GetMockedRateLimitConfig()
err := rateLimitInit(c)
if err != nil {
t.Fatal(err)
}
}

func TestOnUpdate(t *testing.T) {
config := GetMockedRateLimitConfig()
OnUpdate(*config)
}
62 changes: 62 additions & 0 deletions pkg/filter/ratelimit/logger_warpper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this code make sense?

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ratelimit

import "github.com/apache/dubbo-go-pixiu/pkg/logger"

// loggerWrapper
type loggerWrapper struct {
}

// getWrappedLogger
func getWrappedLogger() loggerWrapper {
return loggerWrapper{}
}

func (l loggerWrapper) Debug(msg string, keysAndValues ...interface{}) {
logger.Debugf(msg, keysAndValues)
}

func (l loggerWrapper) Info(msg string, keysAndValues ...interface{}) {
logger.Infof(msg, keysAndValues)
}

func (l loggerWrapper) Warn(msg string, keysAndValues ...interface{}) {
logger.Warnf(msg, keysAndValues)
}

func (l loggerWrapper) Error(err error, msg string, keysAndValues ...interface{}) {
logger.Warnf(msg, err, keysAndValues)
}

// InfoEnabled todo logger should implements this method
func (l loggerWrapper) InfoEnabled() bool {
return true
}

func (l loggerWrapper) ErrorEnabled() bool {
return true
}

func (l loggerWrapper) DebugEnabled() bool {
return true
}

func (l loggerWrapper) WarnEnabled() bool {
return true
}
57 changes: 57 additions & 0 deletions pkg/filter/ratelimit/matcher/exact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package matcher

import (
"github.com/dubbogo/dubbo-go-pixiu-filter/pkg/api/config/ratelimit"
)

import (
"sync"
)

type Exact struct {
apiNames map[string]string

mu sync.RWMutex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI,I think pointer is better

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mu *sync.RWMutex, this way?

}

func (p *Exact) load(apis []ratelimit.Resource) {
m := map[string]string{}

for _, api := range apis {
apiName := api.Name
for _, item := range api.Items {
if item.MatchStrategy == ratelimit.EXACT {
m[item.Pattern] = apiName
}
}
}

p.mu.Lock()
defer p.mu.Unlock()
p.apiNames = m
}

func (p *Exact) match(path string) (string, bool) {
p.mu.RLock()
defer p.mu.RUnlock()

resourceName, ok := p.apiNames[path]
return resourceName, ok
}
66 changes: 66 additions & 0 deletions pkg/filter/ratelimit/matcher/matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package matcher

import (
"github.com/dubbogo/dubbo-go-pixiu-filter/pkg/api/config/ratelimit"
)

var _matcher *Matcher

// Init matcher
func Init() {
_matcher = NewMatcher()
}

//PathMatcher according the url path find APIResource name
type PathMatcher interface {
load(apis []ratelimit.Resource)

match(path string) (string, bool)
}

type Matcher struct {
matchers []PathMatcher
}

func NewMatcher() *Matcher {
return &Matcher{
matchers: []PathMatcher{
&Exact{},
&Regex{},
},
}
}

// Load load api resource for matchers
func Load(apis []ratelimit.Resource) {
for _, v := range _matcher.matchers {
v.load(apis)
}
}

// Match match resource via url path
func Match(path string) (string, bool) {
for _, m := range _matcher.matchers {
if res, ok := m.match(path); ok {
return res, ok
}
}
return "", false
}
Loading