diff --git a/directory_ee.json b/directory_ee.json index ba1a0aa73..f38180daf 100644 --- a/directory_ee.json +++ b/directory_ee.json @@ -275,6 +275,10 @@ { "title": "用户名配额限制", "path": "modules/username_quota" + }, + { + "title": "客户端标签管理", + "path": "modules/client_tag" } ] }, @@ -1517,4 +1521,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/en_US/advanced/rate-limit.md b/en_US/advanced/rate-limit.md index 63b60f98e..a570e0af4 100644 --- a/en_US/advanced/rate-limit.md +++ b/en_US/advanced/rate-limit.md @@ -1,52 +1,56 @@ -# Rate limit +# Rate Limit EMQX Broker specifies the limit on access speed and message speed. When the client's connection request speed exceeds the specified limit, the establishment of a new connection is suspended; when the message reception speed exceeds the specified limit, the reception of messages is suspended. Rate limit is a *backpressure* scheme that avoids system overload from the entrance and guarantees system stability and predictable throughput. The rate limit can be configured in `etc/emqx.conf` : -| Configuration item | Type | Default value | Description | -| ----------------------------------- | --------------- | ------------- | ------------------------------------------------------------ | -| listener.tcp.external.max_conn_rate | Number | 1000 | The maximum allowable connection rate on this node (conn/s) | -| zone.external.rate_limit.conn_messages_in | Number,Duration | No limit | Maximum allowable publish rate on a single connection (msg/s) | -| zone.external.rate_limit.conn_bytes_in | Size,Duration | No limit | Maximum allowable packet rate on a single connection (bytes/s) | +| Configuration Item | Type | Default Value | Description | +| ----------------------------------------- | ---------------- | ------------- | ------------------------------------------------------------ | +| listener.tcp.external.max_conn_rate | Number | 1000 | The maximum allowable connection rate on this node (conn/s) | +| zone.external.rate_limit.conn_messages_in | Number, Duration | No limit | Maximum allowable publish rate on a single connection (msg/s) | +| zone.external.rate_limit.conn_bytes_in | Size, Duration | No limit | Maximum allowable packet rate on a single connection (bytes/s) | -- **max_conn_rate** is the rate limit for connection establishment on a single emqx node. `1000` means that 1000 clients can access at most. +- **max_conn_rate** is the rate limit for connection establishment on a single EMQX node. `1000` means that 1000 clients can access at most. - **conn_messages_in** is the rate limit for receiving PUBLISH packets on a single connection. `100,10s` means that the maximum PUBLISH message rate allowed on each connection is 100 every 10 seconds. - **conn_bytes_in** is the rate limit for receiving TCP packets on a single connection. `100KB,10s` means that the maximum TCP packet rate allowed on each connection is 100KB every 10 seconds. `conn_messages_in` and `conn_bytes_in` both provide limits for a single connection. EMQX Broker currently does not provide a global message rate limit. -## Rate limit explanation +## Rate Limit Explanation EMQX Broker uses the [Token Bucket](https://en.wikipedia.org/wiki/Token_bucket) algorithm to control all Rate Limits. The logic of the token bucket algorithm is as follows: ![image-20190604103907875](../assets/token-bucket.jpg) -- There is a bucket that can hold the maximum burst of the token. The maximum burst is abbreviated as b. -- There is a rate for adding tokens to the bucket per second, abbreviated as r. When the bucket is full, no tokens are added to the bucket. -- Whenever 1 (or N) request arrives, take 1 (or N) token from the bucket. If the token is not enough, it will be blocked and wait for the token to be generated. +- A *bucket* holds tokens, with a maximum capacity of $burst$ tokens, abbreviated as $b$. +- Tokens are added to the bucket at a constant rate $rate$, abbreviated as $r$. When the bucket is full, no additional tokens are added. +- When a request (or N requests) arrives, it must consume 1 (or N) tokens from the bucket. If there are not enough tokens, the request is blocked until more tokens are generated. -It can be seen from this algorithm: +In this algorithm: -- In the long run, the average value of the limited request rate is equal to the value of rate. +1. When a large number of requests arrive and the bucket is full: -- When the actual request reaching speed is M, and M> r, then the maximum (peak) rate that can be achieved in actual operation is M = b + r. + The maximum number of tokens that can be consumed per unit time is $b + r/1$, i.e., all the tokens in the bucket plus those generated during the unit time. -It is easy to think that the maximum rate M is the speed that can consume the full state token bucket in 1 unit of time. The consumption rate of token bucket is M-r, so we can see that: b / (M-r) = 1, and we get M = b + r - - + This is the maximum achievable rate: $M = b + r/1$. -### Application of Token Bucket Algorithm in EMQX Broker +2. After all tokens in the bucket are consumed (i.e., the bucket is empty): + + The number of tokens available per unit time is $0 + r/1$, meaning only newly generated tokens can be consumed. + + This represents the long-term average rate: $r$. + +### Application of Token Bucket Algorithm in EMQX When the following configuration is used for packet rate limiting: ``` zone.external.rate_limit.conn_bytes_in = 100KB,10s ``` -EMQX Broker will initialize the rate-limit processor of each connection with two values: +EMQX will initialize the rate-limit processor of each connection with two values: - rate = 100 KB / 10s = 10240 B/s - burst = 100 KB = 102400 B -According to the algorithm in [Message Rate Limitation Explanation](#rate-limit-explanation), it is known: +According to the algorithm in [Rate Limit Explanation](#rate-limit-explanation), it is known: - In the long run, the allowable average rate is limited to 10240 B/s - The allowable peak rate is 102400 + 10240 = 112640 B/s diff --git a/en_US/modules/client_tag.md b/en_US/modules/client_tag.md new file mode 100644 index 000000000..5b081bb8b --- /dev/null +++ b/en_US/modules/client_tag.md @@ -0,0 +1,122 @@ +# Client Tags and Group-Based Rate Limiting + +Starting from EMQX version 4.4.33, EMQX introduces a client tagging feature. This feature allows you to assign tags to clients based on business logic and apply differentiated rate-limiting policies to clients under different tags. + +This module relies heavily on [HTTP Authentication/ACL](./http_authentication.md), using the data returned from the authentication interface to assign tags to clients. This document details the working mechanism, configuration, and management of client tags. + +## How It Works + +The core principle of client tagging is “group first, then rate limit.” EMQX automatically assigns clients to different groups based on the `tag` returned by the HTTP authentication service, and then applies independent rate-limiting policies to each group. + +The full workflow is as follows: + +1. **Create Tags**: Tags are pre-created in the EMQX Dashboard, each with its own rate-limiting strategy. A built-in `default` tag exists and cannot be deleted. It is used for clients that do not match any tag. +2. **Client Connection**: A client initiates a connection request. +3. **HTTP Authentication**: EMQX sends client information to the external HTTP authentication service. +4. **Tag Assignment**: The authentication service includes tag information in its response based on custom business logic. +5. **Apply Policy**: EMQX parses the tag from the response, associates the client with the corresponding tag, and enforces the rate-limiting policy configured for that tag. + +### Tag Assignment Logic + +- If HTTP authentication is successful (status code `200`) and the `client_attrs.tag` in the response matches a pre-created tag, the client is assigned to that tag. +- If the `tag` field is missing or the value does not match any existing tag, the client is automatically assigned to the `default` tag. +- If HTTP authentication fails (non-`200` status code), the client connection is denied, and no tag is assigned. + +::: tip Note + +You must create tags in the Dashboard first; only then will tags returned by the HTTP service take effect. The rate-limiting policy for the `default` tag can also be customized to control default client behavior. + +If the HTTP Authentication module is not enabled, all clients are automatically assigned to the `default` tag. + +::: + +## HTTP Authentication Interface Specification + +To enable EMQX to recognize client tags, your HTTP authentication service must comply with the following interface specification. + +When authentication is successful, the HTTP service should return a 200 status code and a response body containing a JSON object. The `client_attrs.tag` field in the object specifies the client’s tag. + +**Example Response Body:** + +```json +{ + "result": "allow", + "client_attrs": { + "tag": "group_a" + } +} +``` + +**Field Descriptions:** + +- `result`: `string` type. Currently reserved for EMQX 5.0 compatibility and does not affect authentication results. EMQX determines authentication success based solely on HTTP status code. +- `client_attrs`: `object` type. Stores additional client attributes. + - `tag`: `string` type. Specifies the client’s tag name. EMQX uses this value to group the client. + +## Rate Limiting Policies and Handling + +EMQX provides fine-grained rate-limiting strategies per tag, allowing you to control resource usage per client group. + +### Configurable Limits + +| Limit Type | Unit | Description | +| --------------------------------- | ------------ | ------------------------------------------------------------ | +| Sent Message TPS Limit | Messages/sec | Limits the number of messages a client can publish per second (TPS). | +| Subscribe Message TPS Limit | Messages/sec | Limits the number of messages EMQX can deliver to a client per second. | +| Sent Traffic Limit (bytes/s) | Bytes/sec | Limits the message traffic a client can publish per second. | +| Subscribe Traffic Limit (bytes/s) | Bytes/sec | Limits the message traffic a client can deliver per second. | +| Maximum QoS Level | 0, 1, 2 | Limits the maximum QoS level a client is allowed to publish with. | + +::: tip + +If a limit value is empty or set to `0`, that limit is **not applied**. + +::: + +### Enforcement Mechanism + +When a client exceeds the rate limits configured for its assigned tag, EMQX handles it differently based on the type of limit: + +- **For publishing clients**: + - **QoS Limit**: If a client tries to publish with a QoS level higher than allowed, the message is dropped. + - **Rate/Byte Limit**: If the client exceeds the message or byte rate limit, EMQX applies backpressure, temporarily blocking data reads from the client’s socket to slow down publishing. This behaves similarly to [EMQX’s built-in rate limiting](../advanced/rate-limit.md) but does not disconnect the client. +- **For subscribing clients**: + - **Rate/Byte Limit**: If the message delivery rate exceeds the configured limit, subsequent messages are dropped to prevent the client from being overwhelmed. + +::: tip Note + +For performance reasons, EMQX does not enqueue messages that exceed rate limits. They are dropped immediately. +See: [Inflight Window and Message Queue](../advanced/inflight-window-and-message-queue.md). + +Due to batch processing of message delivery, if the delivery rate or byte limit is set too low, rate limiting may be triggered frequently, causing the actual delivery rate to fall below the configured limit. + +::: + +## Manage Client Tags via Dashboard + +You can manage client tags and their rate-limiting policies conveniently through the EMQX Dashboard. + +1. Open the EMQX Dashboard in your browser. +2. In the left menu, click **Modules**. +3. Click **Add Module** on the page, then select and add **Client Tag Management** from the list. +4. Once added, a **Client Tag Management** module will appear in the module list. Click **Manage** to enter the Client Tag Management page. + +### Client Tags + +Under the **Client Tags** tab, all created tags are displayed in a list, including the built-in `default` tag. You can: + +- **View**: See tag names and the number of currently associated clients. +- **Create**: Click **Add** to add new tags and configure rate-limiting policies. For detailed configuration descriptions, see [Configurable Limits](#configurable-limits). +- **Manage**: Edit rate-limiting strategies or view the client list under a tag by clicking the **View Client List** button. +- **Delete**: Delete a tag that is no longer needed. + +### Client Search + +Under the **Client Search** tab, you can view all online clients assigned to different tags. The list supports pagination, and you can click a client ID to view detailed information for troubleshooting and monitoring. You can quickly locate clients or tags by client ID or tag name. + +## Monitoring and Logs + +To assist with monitoring and debugging group-based rate limiting, EMQX provides relevant metrics and logging support: + +- **Prometheus Metrics**: EMQX exposes metrics for messages dropped due to rate limiting, which can be integrated with monitoring and alerting systems. +- **Logs**: When rate limiting is triggered, EMQX logs the event. The logging system supports **sampling** to avoid performance degradation during traffic spikes. \ No newline at end of file diff --git a/zh_CN/advanced/rate-limit.md b/zh_CN/advanced/rate-limit.md index 0ab175fcb..c8c76bc2c 100644 --- a/zh_CN/advanced/rate-limit.md +++ b/zh_CN/advanced/rate-limit.md @@ -8,7 +8,7 @@ keywords: rate-limit # 描述 description: # 分类 -category: +category: # 引用 ref: --- @@ -35,17 +35,23 @@ EMQX 使⽤[令牌桶 (Token Bucket)](https://en.wikipedia.org/wiki/Token_bucket ![image-20190604103907875](../assets/token-bucket.jpg) -- 存在一个可容纳令牌(Token) 的最大值 burst 的桶(Bucket),最大值 burst 简记为 b 。 -- 存在一个 rate 为每秒向桶添加令牌的速率,简记为 r 。当桶满时则不不再向桶中加⼊入令牌。 -- 每当有 1 个(或 N 个)请求抵达时,则从桶中拿出 1 个 (或 N 个) 令牌。如果令牌不不够则阻塞,等待令牌的⽣生成。 +- 存在一个可容纳令牌 (Token) 的桶 (Bucket) ,可容纳令牌数量的最大值为 $burst$ ,简记为 $b$ 。 +- 存在一个每秒向桶添加令牌的速率 $rate$,简记为 $r$ 。当桶满时则不再向桶中加入令牌。 +- 每当有 1 个 (或 N 个) 请求抵达时,则从桶中拿出 1 个 (或 N 个) 令牌。如果令牌不够则阻塞,等待令牌的生成。 -由此可知该算法中: +该算法中: -- 长期来看,所限制的请求速率的平均值等于 rate 的值。 +1. 在大量请求到达时,假设当前 Bucket 已满。 -- 记实际请求达到速度为 M,且 M > r,那么,实际运⾏中能达到的最大(峰值)速率为 M = b + r,证明: + 那么单位时间内可被请求消耗的 Token 数量最多为 $b + r/1$ 。即桶中的所有 Token 和单位时间内生成的所有 Token。 - 容易想到,最大速率 M 为:能在1个单位时间内消耗完满状态令牌桶的速度。而桶中令牌的消耗速度为 M - r,故可知:b / (M - r) = 1,得 M = b + r + 该速率即为实际能够达到的最大速率。记为 $M = b + r/1$。 + +2. 在桶中 Token 被完全消耗后(Bucket 为空之后) + + 单位时间内可被请求消耗的 Token 数量最多为 $0 + r/1$。即该单位时间内生成的所有 Token。 + + 该速率即为长期来看所能达到的平均速率 $r$ ### 令牌桶算法在 EMQX 中的应用 @@ -60,7 +66,7 @@ EMQX 将使用两个值初始化每个连接的 rate-limit 处理器: - rate = 100 KB / 10s = 10240 B/s - burst = 100 KB = 102400 B -根据 [消息速率限制原理](#rate-limit-explanation) 中的算法,可知: +根据[消息速率限制原理](#速率限制原理)中的算法,可知: - 长期来看允许的平均速率限制为 10240 B/s - 允许的峰值速率为 102400 + 10240 = 112640 B/s diff --git a/zh_CN/modules/client_tag.md b/zh_CN/modules/client_tag.md new file mode 100644 index 000000000..f90d2b074 --- /dev/null +++ b/zh_CN/modules/client_tag.md @@ -0,0 +1,119 @@ +# 客户端标签与分组限流 + +从 4.4.33 版本开始,EMQX 新增了客户端标签管理功能。该功能允许您根据业务需求为客户端打上标签,并对不同标签下的客户端实施差异化的速率限制策略。 + +该模块强依赖于 [HTTP 认证/访问控制](./http_authentication.md),通过解析其认证接口返回的数据来为客户端分配标签。本文将详细介绍客户端标签的工作机制、配置方法和管理方式。 + +## 工作原理 + +客户端标签功能的核心是 “先分组,后限流”。EMQX 根据 HTTP 认证服务返回的标签(Tag)将客户端自动分配到不同的组,然后对每个组的客户端应用独立的速率限制。 + +其完整工作流程如下: + +1. **创建标签**:预先在 EMQX Dashboard 上创建若干标签,并为每个标签配置独立的速率限制策略。系统中存在一个不可删除的 `default` 标签,用于归属未成功匹配任何标签的客户端。 +2. **客户端连接**:客户端发起连接请求。 +3. **HTTP 认证**:EMQX 将客户端信息发送至外部 HTTP 认证服务。 +4. **标签分配**:HTTP 认证服务根据自身的业务逻辑,在返回的响应体中携带客户端的标签信息。 +5. **应用策略**:EMQX 解析响应中的标签,将客户端与对应的标签关联,并对该客户端的后续行为(如消息收发)实施该标签配置的速率限制策略。 + +### 标签分配逻辑 + +- 如果 HTTP 认证成功(响应码 200)且响应体中 `client_attrs.tag` 字段的值为已创建的某个标签,则客户端被分配到该标签下。 +- 如果 `client_attrs` 中无 `tag` 字段,或 `tag` 字段的值不属于任何一个已创建的标签,客户端将被自动分配到 `default` 标签下。 +- 如果 HTTP 认证失败(响应码非 200),客户端连接将被拒绝,不会进行标签分配。 + +::: tip 提示 +您必须首先在 Dashboard 上创建标签,HTTP 服务返回的标签才能生效。`default` 标签的速率限制策略也可以修改,以满足对默认客户端行为的管控需求。 + +如果没有开启 HTTP 认证模块,所有客户端都会直接被归属于 `default` 标签。 +::: + +## HTTP 认证接口规范 + +为了让 EMQX 能够识别客户端标签,您的 HTTP 认证服务必须遵循以下接口规范。 + +当认证成功时,HTTP 服务需要返回 `200` 状态码,并在响应体(Response Body)中包含一个 JSON 对象,其中 `client_attrs.tag` 字段用于指定客户端的标签。 + +**响应体示例:** + +```json +{ + "result": "allow", + "client_attrs": { + "tag": "group_a" + } +} +``` + +**字段说明:** + +- `result`: `string` 类型。当前版本中该字段仅为兼容 EMQX 5.0 预留,不会影响认证结果。EMQX 仅通过 HTTP 状态码判断认证是否成功。 +- `client_attrs`: `object` 类型。用于存放客户端的附加属性。 + - `tag`: `string` 类型。用于指定客户端的标签名。EMQX 会依据此值将客户端分配到对应的标签组。 + +## 限流策略与处理机制 + +EMQX 为每个标签提供精细化的速率限制策略,您可以针对性地管控不同客户端组的资源使用。 + +### 可配置的限制项 + +| 限制项 | 单位 | 说明 | +| ---------------------- | ----------- | ------------------------------------------------ | +| 发送消息 TPS 限制 | `消息数/秒` | 限制单个客户端每秒可发布的消息数量(TPS)。 | +| 订阅消息 TPS 限制 | `消息数/秒` | 限制 EMQX 每秒可向单个客户端投递的消息数量。 | +| 发送流量限制(bytes/s) | `字节数/秒` | 限制单个客户端每秒可发布的消息流量大小。 | +| 订阅流量限制(bytes/s) | `字节数/秒` | 限制 EMQX 每秒可向单个客户端投递的消息流量大小。 | +| 最大 QoS 等级 | `0, 1, 2` | 限制客户端可发布消息的最高 QoS 等级。 | + +::: tip 提示 +如果某个限制项的值为空或为 0,则代表不对此项进行任何限制。 +::: + +### 触发机制 + +当客户端的行为超出了其所在标签配置的限制时,EMQX 将根据限制的类型采取不同的处理措施: + +- **对于发布客户端**: + - **QoS 限制**:当客户端尝试以高于标签所允许的最大 QoS 等级发布消息时,该消息将被直接丢弃。 + - **速率限制**(消息数/秒或字节数/秒):当客户端的发布速率超过限制时,EMQX 将采取反压(Backpressure)策略,暂时阻塞从该客户端 Socket 读取数据,从而减缓其发布速度。这与 EMQX 内置的[速率限制](../advanced/rate-limit.md)功能行为一致,但不会断开客户端连接。 + +- **对于订阅客户端**: + - **速率限制**(消息数/秒或字节数/秒):当 EMQX 向客户端投递消息的速率超过限制时,后续的消息将被直接丢弃,以保证该客户端不会接收过多的消息。 + +::: tip 提示 +出于性能考虑,未对此时超过限流的消息进行入队列操作而是直接进行丢弃。请参考:[飞行窗口和消息队列](../advanced/inflight-window-and-message-queue.md)。 + +由于客户端在接收消息时为批量操作,在订阅消息限制或订阅流量限制较小时,可能频繁触发消息限流机制,从而导致客户端接收消息的速率不能达到实际限制速率。 +::: + +## 通过 Dashboard 管理客户端标签 + +您可以通过 EMQX Dashboard 方便地对客户端标签及其限流策略进行全面的管理。 + +1. 在浏览器中打开 EMQX Dashboard。 + +2. 在左侧导航栏点击**模块**。 + +3. 在页面中点击**添加模块**,在弹出的模块列表中选择并添加**客户端标签管理**。 + +4. 添加后,**客户端标签管理**将出现在模块列表中。点击**管理**进入客户端标签管理页面。 + +### 客户端标签 + +**客户端标签**页面以列表形式展示了系统中所有已创建的标签,包括 `default` 标签。您可以在此页面: + +- **查看**:每个标签的名称、当前关联的客户端数量。 +- **创建**:点击**添加**按钮,可以添加新的标签并为其配置限流策略。具体的限制项配置说明,参考[可配置的限制项](#可配置的限制项)。 +- **管理**:对已有标签进行**编辑**(修改限流策略)或通过点击标签列表中的**查看客户端列表**按钮查看其下的客户端列表。 +- **删除**:删除一个不需要的标签。 + +### 客户端搜索 + +在**客户端搜索**页面下可以查看归属于不同标签下的所有在线客户端。该列表支持分页浏览,并可点击任一客户端 ID 跳转至其详情页面,方便您进行问题排查和状态监控。您可以通过客户端 ID 或标签名称快速定位和查询。 + +## 监控与日志 + +为了便于您观察和调试分组限流功能,EMQX 也提供了相应的监控和日志支持。 + +- **Prometheus 指标**:新增了因速率限制而被丢弃消息的统计指标,方便您集成到监控告警系统中。 +- **日志记录**:当触发限流时,EMQX 会记录相应的事件日志。日志系统支持抽样记录,以避免在流量洪峰期产生过多日志影响系统性能。