diff --git a/apps/emqx/i18n/emqx_limiter_i18n.conf b/apps/emqx/i18n/emqx_limiter_i18n.conf
new file mode 100644
index 000000000..ad7ae11aa
--- /dev/null
+++ b/apps/emqx/i18n/emqx_limiter_i18n.conf
@@ -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.
+ 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: """流入字节率"""
+ }
+ }
+}
diff --git a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl
index cebee0165..0ace62ac0 100644
--- a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl
+++ b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl
@@ -17,6 +17,7 @@
-module(emqx_limiter_schema).
-include_lib("typerefl/include/types.hrl").
+-include_lib("hocon/include/hoconsc.hrl").
-export([
roots/0,
@@ -84,110 +85,43 @@ roots() -> [limiter].
fields(limiter) ->
[
- {bytes_in,
- sc(
- ref(limiter_opts),
- #{
- description =>
- <<
- "The bytes_in limiter.
"
- "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.
"
- "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.
"
- "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.
"
- "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.
"
- "This is used for EMQX internal batch operation"
- "e.g. limite the retainer's deliver rate"
- >>
- }
- )}
+ {bytes_in, sc(ref(limiter_opts), #{desc => ?DESC(bytes_in)})},
+ {message_in, sc(ref(limiter_opts), #{description => ?DESC(message_in)})},
+ {connection, sc(ref(limiter_opts), #{desc => ?DESC(connection)})},
+ {message_routing, sc(ref(limiter_opts), #{desc => ?DESC(message_routing)})},
+ {batch, sc(ref(limiter_opts), #{desc => ?DESC(batch)})}
];
fields(limiter_opts) ->
[
- {rate, sc(rate(), #{default => "infinity", desc => "The rate"})},
+ {rate, sc(rate(), #{default => "infinity", desc => ?DESC(rate)})},
{burst,
sc(
burst_rate(),
#{
default => "0/0s",
- desc =>
- "The burst, This value is based on rate.
\n"
- " This value + rate = the maximum limit that can be achieved when limiter burst."
+ desc => ?DESC(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) ->
[
- {rate, sc(rate(), #{desc => "Rate for this bucket."})},
- {capacity, sc(capacity(), #{desc => "The maximum number of tokens for this bucket."})},
- {initial,
- sc(initial(), #{
- default => "0",
- desc => "The initial number of tokens for this bucket."
- })},
+ {rate, sc(rate(), #{desc => ?DESC(rate)})},
+ {capacity, sc(capacity(), #{desc => ?DESC(capacity)})},
+ {initial, sc(initial(), #{default => "0", desc => ?DESC(initial)})},
{per_client,
sc(
ref(client_bucket),
#{
default => #{},
- desc =>
- "The rate limit for each user of the bucket,"
- " this field is not required"
+ desc => ?DESC(per_client)
}
)}
];
fields(client_bucket) ->
[
- {rate, sc(rate(), #{default => "infinity", desc => "Rate for this bucket."})},
- {initial,
- sc(initial(), #{default => "0", desc => "The initial number of tokens for this bucket."})},
+ {rate, sc(rate(), #{default => "infinity", desc => ?DESC(rate)})},
+ {initial, sc(initial(), #{default => "0", desc => ?DESC(initial)})},
%% low_water_mark add for emqx_channel and emqx_session
%% both modules consume first and then check
%% so we need to use this value to prevent excessive consumption
@@ -196,22 +130,20 @@ fields(client_bucket) ->
sc(
initial(),
#{
- desc =>
- "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.",
+ desc => ?DESC(low_water_mark),
default => "0"
}
)},
{capacity,
sc(capacity(), #{
- desc => "The capacity of the token bucket.",
+ desc => ?DESC(client_bucket_capacity),
default => "infinity"
})},
{divisible,
sc(
boolean(),
#{
- desc => "Is it possible to split the number of requested tokens?",
+ desc => ?DESC(divisible),
default => false
}
)},
@@ -219,7 +151,7 @@ fields(client_bucket) ->
sc(
emqx_schema:duration(),
#{
- desc => "The maximum retry time when acquire failed.",
+ desc => ?DESC(max_retry_time),
default => "10s"
}
)},
@@ -227,7 +159,7 @@ fields(client_bucket) ->
sc(
failure_strategy(),
#{
- desc => "The strategy when all the retries failed.",
+ desc => ?DESC(failure_strategy),
default => force
}
)}