Merge pull request #7699 from lafirest/feat/limiter_i18n

feat(limiter): add i18n support
This commit is contained in:
JianBo He 2022-04-22 10:31:21 +08:00 committed by GitHub
commit 97f28c0d5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 216 additions and 88 deletions

View File

@ -0,0 +1,196 @@
emqx_limiter_schema {
failure_strategy {
desc {
en: """The strategy when all the retries failed."""
zh: """当所有的重试都失败后的处理策略"""
}
label: {
en: """Failure Strategy"""
zh: """失败策略"""
}
}
max_retry_time {
desc {
en: """The maximum retry time when acquire failed."""
zh: """申请失败后,尝试重新申请的时长最大值"""
}
label: {
en: """Max Retry Time"""
zh: """最大重试时间"""
}
}
divisible {
desc {
en: """Is it possible to split the number of requested tokens?"""
zh: """申请的令牌数是否可以被分割"""
}
label: {
en: """Divisible"""
zh: """是否可分割"""
}
}
client_bucket_capacity {
desc {
en: """The capacity of per user."""
zh: """每个使用者的令牌容量上限"""
}
label: {
en: """Capacity"""
zh: """容量"""
}
}
capacity {
desc {
en: """The capacity of this token bucket."""
zh: """该令牌桶的容量"""
}
label: {
en: """Capacity"""
zh: """容量"""
}
}
low_water_mark {
desc {
en: """If the remaining tokens are lower than this value,
the check/consume will succeed, but it will be forced to wait for a short period of time."""
zh: """当桶中剩余的令牌数低于这个值,即使令牌申请成功了,也会被强制暂停一会儿"""
}
label: {
en: """Low Water Mark"""
zh: """低水位线"""
}
}
initial {
desc {
en: """The initial number of tokens for this bucket."""
zh: """桶中的初始令牌数"""
}
label: {
en: """Initial"""
zh: """初始令牌数"""
}
}
rate {
desc {
en: """Rate for this bucket."""
zh: """桶的令牌生成速率"""
}
label: {
en: """Rate"""
zh: """速率"""
}
}
per_client {
desc {
en: """The rate limit for each user of the bucket, this field is not required"""
zh: """对桶的每个使用者的速率控制设置,这个不是必须的"""
}
label: {
en: """Per Client"""
zh: """每个使用者的限制"""
}
}
bucket_cfg {
desc {
en: """Bucket Configs"""
zh: """桶的配置"""
}
label: {
en: """Buckets"""
zh: """桶的配置"""
}
}
burst {
desc {
en: """The burst, This value is based on rate.<br/>
This value + rate = the maximum limit that can be achieved when limiter burst."""
zh: """突发速率。
突发速率允许短时间内速率超过设置的速率值,突发速率 + 速率 = 当前桶能达到的最大速率值"""
}
label: {
en: """Burst"""
zh: """突发速率"""
}
}
batch {
desc {
en: """The batch limiter.
This is used for EMQX internal batch operation
e.g. limite the retainer's deliver rate"""
zh: """批量操作速率控制器。
这是给 EMQX 内部的批量操作使用的,比如用来控制保留消息的派发速率"""
}
label: {
en: """Batch"""
zh: """批量操作"""
}
}
message_routing {
desc {
en: """The message routing limiter.
This is used to limite the deliver rate for this EMQX node.
If the this limiter limit is reached, new publish will be refused"""
zh: """消息派发速率控制器。
这个用来控制当前节点内的消息派发速率,当达到最大速率后,新的推送将会被拒绝"""
}
label: {
en: """Message Routing"""
zh: """消息派发"""
}
}
connection {
desc {
en: """The connection limiter.
This is used to limit the connection rate for this EMQX node.
If the this limiter limit is reached, new connections will be refused"""
zh: """连接速率控制器。
这个用来控制当前节点上的连接速率,当达到最大速率后,新的连接将会被拒绝"""
}
label: {
en: """Connection"""
zh: """连接速率"""
}
}
message_in {
desc {
en: """The message in limiter.
This is used to limit the inbound message numbers for this EMQX node
If the this limiter limit is reached, the restricted client will be slow down even be hung for a while."""
zh: """流入速率控制器。
这个用来控制当前节点上的消息流入速率,当达到最大速率后,会话将会被限速甚至被强制挂起一小段时间"""
}
label: {
en: """Message In"""
zh: """消息流入速率"""
}
}
bytes_in {
desc {
en: """The bytes_in limiter.
This is used to limit the inbound bytes rate for this EMQX node.
If the this limiter limit is reached, the restricted client will be slow down even be hung for a while."""
zh: """流入字节率控制器.
这个是用来控制当前节点上的数据流入的字节率,每条消息将会消耗和其二进制大小等量的令牌,当达到最大速率后,会话将会被限速甚至被强制挂起一小段时间"""
}
label: {
en: """Bytes In"""
zh: """流入字节率"""
}
}
}

View File

@ -17,6 +17,7 @@
-module(emqx_limiter_schema). -module(emqx_limiter_schema).
-include_lib("typerefl/include/types.hrl"). -include_lib("typerefl/include/types.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-export([ -export([
roots/0, roots/0,
@ -84,110 +85,43 @@ roots() -> [limiter].
fields(limiter) -> fields(limiter) ->
[ [
{bytes_in, {bytes_in, sc(ref(limiter_opts), #{desc => ?DESC(bytes_in)})},
sc( {message_in, sc(ref(limiter_opts), #{description => ?DESC(message_in)})},
ref(limiter_opts), {connection, sc(ref(limiter_opts), #{desc => ?DESC(connection)})},
#{ {message_routing, sc(ref(limiter_opts), #{desc => ?DESC(message_routing)})},
description => {batch, sc(ref(limiter_opts), #{desc => ?DESC(batch)})}
<<
"The bytes_in limiter.<br>"
"It is used to limit the inbound bytes rate for this EMQX node."
"If the this limiter limit is reached,"
"the restricted client will be slow down even be hung for a while."
>>
}
)},
{message_in,
sc(
ref(limiter_opts),
#{
description =>
<<
"The message_in limiter.<br>"
"This is used to limit the inbound message numbers for this EMQX node"
"If the this limiter limit is reached,"
"the restricted client will be slow down even be hung for a while."
>>
}
)},
{connection,
sc(
ref(limiter_opts),
#{
description =>
<<
"The connection limiter.<br>"
"This is used to limit the connection rate for this EMQX node"
"If the this limiter limit is reached,"
"New connections will be refused"
>>
}
)},
{message_routing,
sc(
ref(limiter_opts),
#{
description =>
<<
"The message_routing limiter.<br>"
"This is used to limite the deliver rate for this EMQX node"
"If the this limiter limit is reached,"
"New publish will be refused"
>>
}
)},
{batch,
sc(
ref(limiter_opts),
#{
description => <<
"The batch limiter.<br>"
"This is used for EMQX internal batch operation"
"e.g. limite the retainer's deliver rate"
>>
}
)}
]; ];
fields(limiter_opts) -> fields(limiter_opts) ->
[ [
{rate, sc(rate(), #{default => "infinity", desc => "The rate"})}, {rate, sc(rate(), #{default => "infinity", desc => ?DESC(rate)})},
{burst, {burst,
sc( sc(
burst_rate(), burst_rate(),
#{ #{
default => "0/0s", default => "0/0s",
desc => desc => ?DESC(burst)
"The burst, This value is based on rate.<br/>\n"
" This value + rate = the maximum limit that can be achieved when limiter burst."
} }
)}, )},
{bucket, sc(map("bucket_name", ref(bucket_opts)), #{desc => "Buckets config"})} {bucket, sc(map("bucket_name", ref(bucket_opts)), #{desc => ?DESC(bucket_cfg)})}
]; ];
fields(bucket_opts) -> fields(bucket_opts) ->
[ [
{rate, sc(rate(), #{desc => "Rate for this bucket."})}, {rate, sc(rate(), #{desc => ?DESC(rate)})},
{capacity, sc(capacity(), #{desc => "The maximum number of tokens for this bucket."})}, {capacity, sc(capacity(), #{desc => ?DESC(capacity)})},
{initial, {initial, sc(initial(), #{default => "0", desc => ?DESC(initial)})},
sc(initial(), #{
default => "0",
desc => "The initial number of tokens for this bucket."
})},
{per_client, {per_client,
sc( sc(
ref(client_bucket), ref(client_bucket),
#{ #{
default => #{}, default => #{},
desc => desc => ?DESC(per_client)
"The rate limit for each user of the bucket,"
" this field is not required"
} }
)} )}
]; ];
fields(client_bucket) -> fields(client_bucket) ->
[ [
{rate, sc(rate(), #{default => "infinity", desc => "Rate for this bucket."})}, {rate, sc(rate(), #{default => "infinity", desc => ?DESC(rate)})},
{initial, {initial, sc(initial(), #{default => "0", desc => ?DESC(initial)})},
sc(initial(), #{default => "0", desc => "The initial number of tokens for this bucket."})},
%% low_water_mark add for emqx_channel and emqx_session %% low_water_mark add for emqx_channel and emqx_session
%% both modules consume first and then check %% both modules consume first and then check
%% so we need to use this value to prevent excessive consumption %% so we need to use this value to prevent excessive consumption
@ -196,22 +130,20 @@ fields(client_bucket) ->
sc( sc(
initial(), initial(),
#{ #{
desc => desc => ?DESC(low_water_mark),
"If the remaining tokens are lower than this value,\n"
"the check/consume will succeed, but it will be forced to wait for a short period of time.",
default => "0" default => "0"
} }
)}, )},
{capacity, {capacity,
sc(capacity(), #{ sc(capacity(), #{
desc => "The capacity of the token bucket.", desc => ?DESC(client_bucket_capacity),
default => "infinity" default => "infinity"
})}, })},
{divisible, {divisible,
sc( sc(
boolean(), boolean(),
#{ #{
desc => "Is it possible to split the number of requested tokens?", desc => ?DESC(divisible),
default => false default => false
} }
)}, )},
@ -219,7 +151,7 @@ fields(client_bucket) ->
sc( sc(
emqx_schema:duration(), emqx_schema:duration(),
#{ #{
desc => "The maximum retry time when acquire failed.", desc => ?DESC(max_retry_time),
default => "10s" default => "10s"
} }
)}, )},
@ -227,7 +159,7 @@ fields(client_bucket) ->
sc( sc(
failure_strategy(), failure_strategy(),
#{ #{
desc => "The strategy when all the retries failed.", desc => ?DESC(failure_strategy),
default => force default => force
} }
)} )}