# レートリミット

EMQXでは、接続速度やメッセージ速度に制限を設けることができ、システムの入口での過負荷を回避し、予測可能なスループットでシステムの安定性を保証するバックプレッシャー方式を採用しています。

## リスナーレベルのリミッター

リミッターはリスナーレベルで動作します。EMQXでは以下の種類のリミッターを使用してレートリミットを指定します。

| 種類           | ダッシュボードUI                                   | 説明                                                        | 過負荷時の動作                  |
| :------------- | ------------------------------------------------- | :----------------------------------------------------------- | :------------------------------ |
| bytes_rate     | Max Message Publishing Traffic (Per Client)       | 単一クライアントが1秒あたりにパブリッシュするメッセージのバイト数 | クライアントからのメッセージ受信を一時停止 |
| bytes_burst    | Max Message Publishing Traffic Burst (Per Client) | 通常の `Data Publishing Rate` に基づく、単一クライアントがバーストで送信可能なバイト数 | クライアントからのメッセージ受信を一時停止 |
| messages_rate  | Max Message Publishing Rate (Per Client)          | 単一クライアントが1秒あたりにパブリッシュするメッセージ数 | クライアントからのメッセージ受信を一時停止 |
| messages_burst | Max Message Publishing Burst (Per Client)         | 通常の `Messages Publish Rate` に加えて、単一クライアントがバーストで送信可能なメッセージ数 | クライアントからのメッセージ受信を一時停止 |
| max_conn_rate  | Max Connection Rate (Listener)                    | 現在のリスナーに対する1秒あたりの接続数                   | 新規接続の受け入れを一時停止   |
| max_conn_rate  | Max Connection Burst (Listener)                   | リスナーがバーストで受け入れ可能な最大接続数               | 新規接続の受け入れを一時停止   |

### リスナーレベルのリミッター設定

ダッシュボードの **Management** -> **Listeners** ページで各リスナーのレートリミットを設定できます。

または、設定ファイルで設定することも可能です。例えば、デフォルトのTCPリスナーにリミッターを設定する場合、`emqx.conf` ファイルに以下のように記述します。

```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"
  bytes_rate = "1MB/s"
  bytes_burst = "100MB/60m"
}
```

この設定は以下を意味します：

- リスナーの接続確立の最大レートは1秒あたり1000接続です。
- リスナーは60分間で最大10,000接続のバーストを受け入れ可能です。
- クライアントごとのメッセージの最大パブリッシュレートは1秒あたり1000メッセージです。
- リスナーは60分間に短時間で最大10,000メッセージのバーストを許容します。
- クライアントごとのデータの最大パブリッシュレートは1秒あたり1MBです。
- リスナーは60分間に短時間で最大100MBのバーストを許容します。

## ノードレベルのリミッター

リミッターはノードレベルでも動作し、各EMQXノードへの個々のクライアント接続速度や、ノードへのメッセージやデータのパブリッシュ速度を制限します。EMQXノードでは以下の種類のリミッターを使用してレートリミットを指定します。

| 種類           | ダッシュボードUI             | 説明                                                        | 過負荷時の動作                                               |
| -------------- | ---------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| bytes_rate     | Data Publish Rate            | 単一クライアントが各EMQXノードに送信するデータ量（バイト単位） | 制限に達すると、QoS 0メッセージは破棄され、QoS 1およびQoS 2メッセージは「Quota Exceeded」エラー（0x97）で拒否されます。 |
| bytes_burst    | Data Publish Burst           | 通常の `data publish rate` に基づく、クライアントごとのデータバースト量 | 制限に達すると、QoS 0メッセージは破棄され、QoS 1およびQoS 2メッセージは「Quota Exceeded」エラー（0x97）で拒否されます。 |
| messages_rate  | Message Publish Rate         | 単一クライアントが各EMQXノードに送信するメッセージのレート | 制限に達すると、QoS 0メッセージは破棄され、QoS 1およびQoS 2メッセージは「Quota Exceeded」エラー（0x97）で拒否されます。 |
| messages_burst | Message Publish Burst        | 通常の `message publishing rate` に基づく、ノードごとに許可されるメッセージのバースト数 | 制限に達すると、QoS 0メッセージは破棄され、QoS 1およびQoS 2メッセージは「Quota Exceeded」エラー（0x97）で拒否されます。 |
| max_conn_rate  | Maximum Connection Rate      | ノードごとに受け入れる新規接続のレート                       | 制限に達すると、Acceptキューでの接続処理が一時停止され、新規接続が遅延または拒否されます。 |
| max_conn_burst | Maximum Connection Burst     | ノードがバーストで受け入れ可能な最大接続数                   | 新規接続の受け入れを一時停止                                |

### ノードレベルのリミッター設定

ダッシュボードの **Management** -> **MQTT Configuration** ページで各ノードのレートリミットを設定できます。

または、設定ファイルで設定することも可能です。例えば、`emqx.conf` に以下のように記述します。

```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 {...}
}
```

- ノードは10秒ごとに最大500メッセージを受信でき、それを超えると破棄または拒否されます。
- ノードは60分間に短時間で最大10,000メッセージのバーストを許容します。
- ノードは10秒ごとに最大500MBのデータを受信でき、それを超えると破棄または拒否されます。
- ノードは60分間に短時間で最大100MBのバーストを許容します。

## レート単位

### 時間単位

レート値でサポートされている時間単位は以下の通りです：

- **s** : 秒
- **m** : 分
- **h** : 時間
- **d** : 日

時間単位は間隔値としても指定可能で、例えば `1000/10s` は「10秒ごとに1000」の制限を意味します。

### サイズ単位

レート値でサポートされているサイズ単位は以下の通りです：

- **KB** : キロバイト
- **MB** : メガバイト
- **GB** : ギガバイト
