# 速率限制器配置

速率限制器自 EMQX 5.0 引入，用于限制连接速率，以及客户端发布和接收消息、传输数据和发送 `SUBSCRIBE` 报文的速率。有关速率限制器及其工作原理的更多信息，请参见[速率限制](../rate-limit.md)。

## 监听器级别限制器

限制器可以在监听器级别上工作，EMQX 使用以下几种类型的限制器来限制速率:

| 类型           | Dashboard 字段名                     | 描述                                                         | 过载后行为         |
| :------------- | :----------------------------------- | :----------------------------------------------------------- | :----------------- |
| bytes_rate     | 最大消息发布流量（单客户端）         | 单个客户端每秒发布的消息的字节数大小。                         | 暂停接收客户端消息 |
| bytes_burst    | 最大消息发布流量突发速率（单客户端） | 单个客户端在常规 `数据发布速率` 基础上允许突发发送的数据量。   | 暂停接收客户端消息 |
| messages_rate  | 最大消息发布速率（单客户端）         | 单个客户端每秒发布的消息条数。                                 | 暂停接收客户端消息 |
| messages_burst | 最大消息发布突发速率（单客户端）     | 在常规 `消息发布速率` 基础上，每个客户端允许突发发送的消息数量。 | 暂停接收客户端消息 |
| subscribes_rate | 订阅速率                            | 单个客户端连接在配置的时间间隔内可发送的最大 `SUBSCRIBE` 报文数量。 | 不处理该报文，也不创建其中的订阅；在 `SUBACK` 中为每个主题过滤器返回失败码。 |
| subscribes_burst | 订阅突发速率                        | 单个客户端连接在突发情况下可额外发送的 `SUBSCRIBE` 报文数量。  | 同上               |
| max_conn_rate  | 最大连接速率（监听器）               | 当前监听器每秒的连接数。                                       | 暂停接收新的连接   |
| max_conn_burst | 最大连接突发速率（监听器）           | 在突发情况下当前监听器可以接受的最大连接数。                   | 暂停接收新的连接   |

投递速率限制器同样在监听器级别生效，但过载行为有所不同，详见[投递速率限制器](#投递速率限制器)。

例如，要为默认的 TCP 监听器设置一个限制器，您可以使用以下配置：

```bash
listeners.tcp.default {
  bind = "0.0.0.0:1883"
  max_conn_rate = "1000/s"
  max_conn_burst = "10000/60m"
  messages_rate = "1000/s"
  messages_burst = "10000/60m"
  subscribes_rate = "120/1m"
  subscribes_burst = "10/10s"
  bytes_rate = "1MB/s"
  bytes_burst = "100MB/60m"
}
```

该配置表示：

- 监听器上连接建立最大速率为每秒 1000 个。
- 在 60 分钟内，监听器上允许接受最多 10000 个连接。
- 消息的最大发布速率为每个客户端每秒 1000 条。
- 每 60 分钟允许在短时间内突发发送最多 10000 条消息。
- 单个客户端每分钟最多发送 120 个 `SUBSCRIBE` 报文，并允许每 10 秒突发发送最多 10 个额外报文。
- 数据的最大发布速率为每个客户端每秒 1MB。
- 每 60 分钟允许在短时间内突发发送最多 100 兆字节。

订阅报文速率限制分别应用于每个客户端连接。该限流器统计报文数量，而不是主题过滤器数量。达到限制后，EMQX 不处理该报文，也不创建其中的订阅，但会保持客户端连接。对于 MQTT 5.0，EMQX 返回 `SUBACK`，其中每个主题过滤器对应的原因码均为 `Quota Exceeded`（0x97）。对于 MQTT 3.x，EMQX 在 `SUBACK` 中为每个主题过滤器返回失败返回码（0x80）。

`subscribes_rate` 的默认值为 `infinity`，即不限制订阅报文速率。为托管命名空间配置订阅报文速率限制后，该配置会覆盖命名空间内客户端所使用的监听器级订阅报文速率限制。

## 节点级别监听器

限制器还可以在节点级别上工作，限制单个客户端连接每个 EMQX 节点的速度和向节点发布消息和数据的速率。EMQX 节点使用以下几种类型的限制器来限制速率:

| 类型           | Dashboard  字段名 | 描述                                                         | 过载后行为                                                   |
| :------------- | ----------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| bytes_rate     | 数据发布速率      | 单个客户端向每个 EMQX 节点发布的数据量。                       | 当达到限制时，EMQX 将丢弃 QoS 0 消息，并以 "配额超限" 错误码 (0x97) 拒绝 QoS 1 和 QoS 2 消息。 |
| bytes_burst    | 数据发布突发速率  | 在常规 `数据发布速率` 基础上允许突发发送的数据量。             | 当达到限制时，EMQX 将丢弃 QoS 0 消息，并以 "配额超限" 错误码 (0x97) 拒绝 QoS 1 和 QoS 2 消息。 |
| messages_rate  | 消息发布速率      | 单个客户端向每个 EMQX 节点发布消息的速率。                     | 当达到限制时，EMQX 将丢弃 QoS 0 消息，并以 "配额超限" 错误码 (0x97) 拒绝 QoS 1 和 QoS 2 消息。 |
| messages_burst | 消息发布突发速率  | 在常规 `消息发布速率` 基础上，每个节点允许突发发送的消息数量。 | 当达到限制时，EMQX 将丢弃 QoS 0 消息，并以 "配额超限" 错误码 (0x97) 拒绝 QoS 1 和 QoS 2 消息。 |
| max_conn_rate  | 最大连接速率      | 每个节点上接受新连接的速率。                                   | 当达到限制时，EMQX 将暂停处理 Accept 队列中的连接，从而延迟或拒绝新连接。 |
| max_conn_burst | 最大连接突发速率  | 每个节点在常规速率基础上可突发接受的连接数。                   | 暂停接收新的连接                                             |

例如，要为节点设置一个限制器，您可以使用以下配置：

```bash
mqtt.limiter {
  max_conn_rate = "1000/s"
  max_conn_burst = "10000/60m"
  messages_rate = "500/10s"
  messages_burst = "10000/60m"
  bytes_rate = "500KB/s"
  bytes_burst = "100MB/60m"
}
```

节点级别限制器可以嵌入到 `zone` 配置中，如下所示：

```bash
zones.my_zone.mqtt {
  limiter {...}
}
```

该配置表示：

- 每个节点上每秒最多接受 1000 个连接。
- 每 60 分钟允许在短时间内突发接受最多 10000 个连接。
- 每个节点上每 10 秒最多接收 500 条消息，超出部分将被丢弃/拒绝。
- 每 60 分钟允许在短时间内突发发送最多 10000 条消息。
- 每个节点上每 10 秒最多接收 500 兆字节，超出部分将被丢弃/拒绝。
- 每 60 分钟允许在短时间内突发发送最多 100 兆字节。

## 投递速率限制器

除上述发布端限制器外，EMQX 还支持订阅端的投递速率限制。这些限制器控制 EMQX 向订阅客户端投递消息的速率，与消息由哪些客户端发布无关。

| 类型                    | Dashboard 字段名                       | 描述                                                         | 过载后行为                                                   |
| ----------------------- | -------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| delivery_messages_rate  | 最大消息投递速率（单客户端）           | 每个节点向单个订阅者投递消息的最大速率。                       | QoS 0 消息将被丢弃；QoS 1 和 QoS 2 消息将在内部排队，并按照限制器配置推算的延迟时间后重试投递。 |
| delivery_messages_burst | 最大消息投递突发速率（单客户端）       | 在常规 `delivery_messages_rate` 基础上允许的突发量。           | 同上。                                                       |
| delivery_bytes_rate     | 最大消息投递流量（单客户端）           | 每个节点向单个订阅者投递数据的最大速率（字节）。               | QoS 0 消息将被丢弃；QoS 1 和 QoS 2 消息将在内部排队，并按照限制器配置推算的延迟时间后重试投递。 |
| delivery_bytes_burst    | 最大消息投递流量突发速率（单客户端）   | 在常规 `delivery_bytes_rate` 基础上允许的突发量。              | 同上。                                                       |

当 QoS 1 或 QoS 2 消息因达到投递速率限制而无法立即投递时，EMQX 会将该消息与后续 QoS 1 和 QoS 2 消息一起入队。这样可避免投递速率限制器本身导致后续消息越过先前消息。

与发布端限制器不同，投递限制器为通道独立限制器，作用于单个客户端连接，不在 zone 或监听器之间共享。

:::tip
投递速率限制器仅支持内存会话（`durable_sessions.enable = false`），在持久化会话模式下不生效。
:::

您可以在 Dashboard 的**管理** -> **监听器**页面中，为每个监听器设置投递速率限制。

也可以通过配置文件设置，例如，要为默认的 TCP 监听器设置投递速率限制，可以在 emqx.conf 中按以下进行配置：

```bash
listeners.tcp.default {
  bind = "0.0.0.0:1883"
  delivery_messages_rate = "100/s"
  delivery_messages_burst = "500/10s"
  delivery_bytes_rate = "1MB/s"
  delivery_bytes_burst = "10MB/10s"
}
```

如未配置，默认值为 `infinity`，保持向后兼容。

::: tip

EMQX 提供了更多配置项以更好地满足定制化需求。详情请参见 [EMQX 企业版配置手册](https://docs.emqx.com/zh/enterprise/v6.3.1/hocon/)。

:::
