Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
2
22a7f0099
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Summer2022
22a7f0099
Commits
dec6c16d
Commit
dec6c16d
authored
5 years ago
by
Ming Deng
Browse files
Options
Downloads
Patches
Plain Diff
Refactor MethodServiceTpsLimitImpl; Read config from yml
parent
225b90d1
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
config/method_config.go
+9
-6
9 additions, 6 deletions
config/method_config.go
config/service_config.go
+47
-31
47 additions, 31 deletions
config/service_config.go
filter/impl/tps_limiter_method_service_impl.go
+46
-46
46 additions, 46 deletions
filter/impl/tps_limiter_method_service_impl.go
with
102 additions
and
83 deletions
config/method_config.go
+
9
−
6
View file @
dec6c16d
...
...
@@ -25,12 +25,15 @@ import (
)
type
MethodConfig
struct
{
InterfaceId
string
InterfaceName
string
Name
string
`yaml:"name" json:"name,omitempty" property:"name"`
Retries
string
`yaml:"retries" json:"retries,omitempty" property:"retries"`
Loadbalance
string
`yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
Weight
int64
`yaml:"weight" json:"weight,omitempty" property:"weight"`
InterfaceId
string
InterfaceName
string
Name
string
`yaml:"name" json:"name,omitempty" property:"name"`
Retries
string
`yaml:"retries" json:"retries,omitempty" property:"retries"`
Loadbalance
string
`yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
Weight
int64
`yaml:"weight" json:"weight,omitempty" property:"weight"`
TpsLimitInterval
string
`yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"`
TpsLimitRate
string
`yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"`
TpsLimitStrategy
string
`yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"`
}
func
(
c
*
MethodConfig
)
Prefix
()
string
{
...
...
This diff is collapsed.
Click to expand it.
config/service_config.go
+
47
−
31
View file @
dec6c16d
...
...
@@ -43,27 +43,32 @@ import (
)
type
ServiceConfig
struct
{
context
context
.
Context
id
string
Filter
string
`yaml:"filter" json:"filter,omitempty" property:"filter"`
Protocol
string
`default:"dubbo" required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"`
//multi protocol support, split by ','
InterfaceName
string
`required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"`
Registry
string
`yaml:"registry" json:"registry,omitempty" property:"registry"`
Cluster
string
`default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"`
Loadbalance
string
`default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
Group
string
`yaml:"group" json:"group,omitempty" property:"group"`
Version
string
`yaml:"version" json:"version,omitempty" property:"version" `
Methods
[]
*
MethodConfig
`yaml:"methods" json:"methods,omitempty" property:"methods"`
Warmup
string
`yaml:"warmup" json:"warmup,omitempty" property:"warmup"`
Retries
string
`yaml:"retries" json:"retries,omitempty" property:"retries"`
Params
map
[
string
]
string
`yaml:"params" json:"params,omitempty" property:"params"`
Token
string
`yaml:"token" json:"token,omitempty" property:"token"`
AccessLog
string
`yaml:"accesslog" json:"accesslog,omitempty" property:"accesslog"`
unexported
*
atomic
.
Bool
exported
*
atomic
.
Bool
rpcService
common
.
RPCService
cacheProtocol
protocol
.
Protocol
cacheMutex
sync
.
Mutex
context
context
.
Context
id
string
Filter
string
`yaml:"filter" json:"filter,omitempty" property:"filter"`
Protocol
string
`default:"dubbo" required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"`
// multi protocol support, split by ','
InterfaceName
string
`required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"`
Registry
string
`yaml:"registry" json:"registry,omitempty" property:"registry"`
Cluster
string
`default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"`
Loadbalance
string
`default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
Group
string
`yaml:"group" json:"group,omitempty" property:"group"`
Version
string
`yaml:"version" json:"version,omitempty" property:"version" `
Methods
[]
*
MethodConfig
`yaml:"methods" json:"methods,omitempty" property:"methods"`
Warmup
string
`yaml:"warmup" json:"warmup,omitempty" property:"warmup"`
Retries
string
`yaml:"retries" json:"retries,omitempty" property:"retries"`
Params
map
[
string
]
string
`yaml:"params" json:"params,omitempty" property:"params"`
Token
string
`yaml:"token" json:"token,omitempty" property:"token"`
AccessLog
string
`yaml:"accesslog" json:"accesslog,omitempty" property:"accesslog"`
TpsLimiter
string
`yaml:"tps.limiter" json:"tps.limiter,omitempty" property:"tps.limiter"`
TpsLimitInterval
string
`yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"`
TpsLimitRate
string
`yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"`
TpsLimitStrategy
string
`yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"`
TpsLimitRejectedHandler
string
`yaml:"tps.limit.rejected.handler" json:"tps.limit.rejected.handler,omitempty" property:"tps.limit.rejected.handler"`
unexported
*
atomic
.
Bool
exported
*
atomic
.
Bool
rpcService
common
.
RPCService
cacheProtocol
protocol
.
Protocol
cacheMutex
sync
.
Mutex
}
func
(
c
*
ServiceConfig
)
Prefix
()
string
{
...
...
@@ -94,9 +99,9 @@ func NewServiceConfig(id string, context context.Context) *ServiceConfig {
}
func
(
srvconfig
*
ServiceConfig
)
Export
()
error
{
//TODO: config center start here
//
TODO: config center start here
//TODO:delay export
//
TODO:delay export
if
srvconfig
.
unexported
!=
nil
&&
srvconfig
.
unexported
.
Load
()
{
err
:=
perrors
.
Errorf
(
"The service %v has already unexported! "
,
srvconfig
.
InterfaceName
)
logger
.
Errorf
(
err
.
Error
())
...
...
@@ -111,7 +116,7 @@ func (srvconfig *ServiceConfig) Export() error {
urlMap
:=
srvconfig
.
getUrlMap
()
for
_
,
proto
:=
range
loadProtocol
(
srvconfig
.
Protocol
,
providerConfig
.
Protocols
)
{
//registry the service reflect
//
registry the service reflect
methods
,
err
:=
common
.
ServiceMap
.
Register
(
proto
.
Name
,
srvconfig
.
rpcService
)
if
err
!=
nil
{
err
:=
perrors
.
Errorf
(
"The service %v export the protocol %v error! Error message is %v ."
,
srvconfig
.
InterfaceName
,
proto
.
Name
,
err
.
Error
())
...
...
@@ -164,7 +169,7 @@ func (srvconfig *ServiceConfig) Implement(s common.RPCService) {
func
(
srvconfig
*
ServiceConfig
)
getUrlMap
()
url
.
Values
{
urlMap
:=
url
.
Values
{}
//first set user params
//
first set user params
for
k
,
v
:=
range
srvconfig
.
Params
{
urlMap
.
Set
(
k
,
v
)
}
...
...
@@ -177,7 +182,7 @@ func (srvconfig *ServiceConfig) getUrlMap() url.Values {
urlMap
.
Set
(
constant
.
GROUP_KEY
,
srvconfig
.
Group
)
urlMap
.
Set
(
constant
.
VERSION_KEY
,
srvconfig
.
Version
)
urlMap
.
Set
(
constant
.
ROLE_KEY
,
strconv
.
Itoa
(
common
.
PROVIDER
))
//application info
//
application info
urlMap
.
Set
(
constant
.
APPLICATION_KEY
,
providerConfig
.
ApplicationConfig
.
Name
)
urlMap
.
Set
(
constant
.
ORGANIZATION_KEY
,
providerConfig
.
ApplicationConfig
.
Organization
)
urlMap
.
Set
(
constant
.
NAME_KEY
,
providerConfig
.
ApplicationConfig
.
Name
)
...
...
@@ -186,16 +191,27 @@ func (srvconfig *ServiceConfig) getUrlMap() url.Values {
urlMap
.
Set
(
constant
.
OWNER_KEY
,
providerConfig
.
ApplicationConfig
.
Owner
)
urlMap
.
Set
(
constant
.
ENVIRONMENT_KEY
,
providerConfig
.
ApplicationConfig
.
Environment
)
//filter
//
filter
urlMap
.
Set
(
constant
.
SERVICE_FILTER_KEY
,
mergeValue
(
providerConfig
.
Filter
,
srvconfig
.
Filter
,
constant
.
DEFAULT_SERVICE_FILTERS
))
//filter special config
//
filter special config
urlMap
.
Set
(
constant
.
ACCESS_LOG_KEY
,
srvconfig
.
AccessLog
)
// tps limiter
urlMap
.
Set
(
constant
.
TPS_LIMIT_STRATEGY_KEY
,
srvconfig
.
TpsLimitStrategy
)
urlMap
.
Set
(
constant
.
TPS_LIMIT_INTERVAL_KEY
,
srvconfig
.
TpsLimitInterval
)
urlMap
.
Set
(
constant
.
TPS_LIMIT_RATE_KEY
,
srvconfig
.
TpsLimitRate
)
urlMap
.
Set
(
constant
.
TPS_LIMITER_KEY
,
srvconfig
.
TpsLimiter
)
urlMap
.
Set
(
constant
.
TPS_REJECTED_EXECUTION_HANDLER_KEY
,
srvconfig
.
TpsLimitRejectedHandler
)
for
_
,
v
:=
range
srvconfig
.
Methods
{
urlMap
.
Set
(
"methods."
+
v
.
Name
+
"."
+
constant
.
LOADBALANCE_KEY
,
v
.
Loadbalance
)
urlMap
.
Set
(
"methods."
+
v
.
Name
+
"."
+
constant
.
RETRIES_KEY
,
v
.
Retries
)
urlMap
.
Set
(
"methods."
+
v
.
Name
+
"."
+
constant
.
WEIGHT_KEY
,
strconv
.
FormatInt
(
v
.
Weight
,
10
))
prefix
:=
"methods."
+
v
.
Name
+
"."
urlMap
.
Set
(
prefix
+
constant
.
LOADBALANCE_KEY
,
v
.
Loadbalance
)
urlMap
.
Set
(
prefix
+
constant
.
RETRIES_KEY
,
v
.
Retries
)
urlMap
.
Set
(
prefix
+
constant
.
WEIGHT_KEY
,
strconv
.
FormatInt
(
v
.
Weight
,
10
))
urlMap
.
Set
(
prefix
+
constant
.
TPS_LIMIT_STRATEGY_KEY
,
srvconfig
.
TpsLimitStrategy
)
urlMap
.
Set
(
prefix
+
constant
.
TPS_LIMIT_INTERVAL_KEY
,
srvconfig
.
TpsLimitInterval
)
urlMap
.
Set
(
prefix
+
constant
.
TPS_LIMIT_RATE_KEY
,
srvconfig
.
TpsLimitRate
)
}
return
urlMap
...
...
This diff is collapsed.
Click to expand it.
filter/impl/tps_limiter_method_service_impl.go
+
46
−
46
View file @
dec6c16d
...
...
@@ -46,8 +46,8 @@ func init() {
* interface : "com.ikurento.user.UserProvider"
* ... # other configuration
* tps.limiter: "method-service" # the name of MethodServiceTpsLimiterImpl. It's the default limiter too.
* tps.interval: 5000 # interval, the time unit is ms
* tps.rate: 300 # the max value in the interval. <0 means that the service will not be limited.
* tps.
limit.
interval: 5000 # interval, the time unit is ms
* tps.
limit.
rate: 300 # the max value in the interval. <0 means that the service will not be limited.
* methods:
* - name: "GetUser"
* tps.interval: 3000
...
...
@@ -61,66 +61,66 @@ type MethodServiceTpsLimiterImpl struct {
func
(
limiter
MethodServiceTpsLimiterImpl
)
IsAllowable
(
url
common
.
URL
,
invocation
protocol
.
Invocation
)
bool
{
serviceLimitRate
,
err
:=
strconv
.
ParseInt
(
url
.
GetParam
(
constant
.
TPS_LIMIT_RATE_KEY
,
constant
.
DEFAULT_TPS_LIMIT_RATE
),
0
,
0
)
methodConfigPrefix
:=
"methods."
+
invocation
.
MethodName
()
+
"."
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Can not parse the %s for url %s, please check your configuration!"
,
constant
.
TPS_LIMIT_RATE_KEY
,
url
.
String
()))
}
methodLimitRateConfig
:=
invocation
.
AttachmentsByKey
(
constant
.
TPS_LIMIT_RATE_KEY
,
""
)
methodLimitRateConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_RATE_KEY
,
""
)
methodIntervalConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_INTERVAL_KEY
,
""
)
// both method-level and service-level don't have the configuration of tps limit
if
serviceLimitRate
<
0
&&
len
(
methodLimitRateConfig
)
<=
0
{
return
true
limitTarget
:=
url
.
ServiceKey
()
// method-level tps limit
if
len
(
methodIntervalConfig
)
>
0
||
len
(
methodLimitRateConfig
)
>
0
{
limitTarget
=
limitTarget
+
"#"
+
invocation
.
MethodName
()
}
limitRate
:=
serviceLimitRate
// the method has tps limit configuration
if
len
(
methodLimitRateConfig
)
>
0
{
limitRate
,
err
=
strconv
.
ParseInt
(
methodLimitRateConfig
,
0
,
0
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Can not parse the %s for invocation %s # %s, please check your configuration!"
,
constant
.
TPS_LIMIT_RATE_KEY
,
url
.
ServiceKey
(),
invocation
.
MethodName
()))
}
limitState
,
found
:=
limiter
.
tpsState
.
Load
(
limitTarget
)
if
found
{
return
limitState
.
(
filter
.
TpsLimitStrategy
)
.
IsAllowable
()
}
// 1. the serviceLimitRate < 0 and methodRateConfig is empty string
// 2. the methodLimitRate < 0
if
limitRate
<
0
{
limitRate
:=
getLimitConfig
(
methodLimitRateConfig
,
url
,
invocation
,
constant
.
TPS_LIMIT_RATE_KEY
,
constant
.
DEFAULT_TPS_LIMIT_RATE
)
if
limitRate
<
0
{
return
true
}
serviceInterval
,
err
:=
strconv
.
ParseInt
(
url
.
GetParam
(
constant
.
TPS_LIMIT_INTERVAL_KEY
,
constant
.
DEFAULT_TPS_LIMIT_INTERVAL
),
0
,
0
)
if
err
!=
nil
||
serviceInterval
<=
0
{
panic
(
fmt
.
Sprintf
(
"The %s must be positive, please check your configuration!"
,
constant
.
TPS_LIMIT_INTERVAL_KEY
))
limitInterval
:=
getLimitConfig
(
methodIntervalConfig
,
url
,
invocation
,
constant
.
TPS_LIMIT_INTERVAL_KEY
,
constant
.
DEFAULT_TPS_LIMIT_INTERVAL
)
if
limitInterval
<=
0
{
panic
(
fmt
.
Sprintf
(
"The interval must be positive, please check your configuration! url: %s"
,
url
.
String
()))
}
limitInterval
:=
serviceInterval
methodIntervalConfig
:=
invocation
.
AttachmentsByKey
(
constant
.
TPS_LIMIT_INTERVAL_KEY
,
""
)
// there is the interval configuration of method-level
if
len
(
methodIntervalConfig
)
>
0
{
limitInterval
,
err
=
strconv
.
ParseInt
(
methodIntervalConfig
,
0
,
0
)
if
err
!=
nil
||
limitInterval
<=
0
{
limitStrategyConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_STRATEGY_KEY
,
url
.
GetParam
(
constant
.
TPS_LIMIT_STRATEGY_KEY
,
constant
.
DEFAULT_KEY
))
limitStateCreator
:=
extension
.
GetTpsLimitStrategyCreator
(
limitStrategyConfig
)
limitState
,
_
=
limiter
.
tpsState
.
LoadOrStore
(
limitTarget
,
limitStateCreator
(
int
(
limitRate
),
int
(
limitInterval
)))
return
limitState
.
(
filter
.
TpsLimitStrategy
)
.
IsAllowable
()
}
func
getLimitConfig
(
methodLevelConfig
string
,
url
common
.
URL
,
invocation
protocol
.
Invocation
,
configKey
string
,
defaultVal
string
)
int64
{
if
len
(
methodLevelConfig
)
>
0
{
result
,
err
:=
strconv
.
ParseInt
(
methodLevelConfig
,
0
,
0
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"The %s for invocation %s # %s must be positive, please check your configuration!"
,
con
stant
.
TPS_LIMIT_INTERVAL_KEY
,
url
.
ServiceKey
(),
invocation
.
MethodName
()))
con
figKey
,
url
.
ServiceKey
(),
invocation
.
MethodName
()))
}
return
result
}
limitTarget
:=
url
.
ServiceKey
(
)
result
,
err
:=
strconv
.
ParseInt
(
url
.
GetParam
(
configKey
,
defaultVal
),
0
,
0
)
// method-level tps limit
if
len
(
methodIntervalConfig
)
>
0
||
len
(
methodLimitRateConfig
)
>
0
{
limitTarget
=
limitTarget
+
"#"
+
invocation
.
MethodName
()
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Cannot parse the configuration %s, please check your configuration!"
,
configKey
))
}
limitStrategyConfig
:=
invocation
.
AttachmentsByKey
(
constant
.
TPS_LIMIT_STRATEGY_KEY
,
url
.
GetParam
(
constant
.
TPS_LIMIT_STRATEGY_KEY
,
constant
.
DEFAULT_KEY
))
limitStateCreator
:=
extension
.
GetTpsLimitStrategyCreator
(
limitStrategyConfig
)
limitState
,
_
:=
limiter
.
tpsState
.
LoadOrStore
(
limitTarget
,
limitStateCreator
(
int
(
limitRate
),
int
(
limitInterval
)))
return
limitState
.
(
filter
.
TpsLimitStrategy
)
.
IsAllowable
()
return
result
}
var
methodServiceTpsLimiterInstance
*
MethodServiceTpsLimiterImpl
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment