| --- |
| title: mqtt-proxy |
| keywords: |
| - APISIX |
| - API 网关 |
| - Plugin |
| - MQTT Proxy |
| description: 本文档介绍了 Apache APISIX mqtt-proxy 插件的信息,通过 `mqtt-proxy` 插件可以使用 MQTT 的 `client_id` 进行动态负载平衡。 |
| --- |
| |
| <!-- |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| --> |
| |
| ## 描述 |
| |
| 通过 `mqtt-proxy` 插件可以使用 MQTT 的 `client_id` 进行动态负载平衡。它仅适用于 `stream` 模式。 |
| |
| 这个插件支持 MQTT [3.1.*](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html) 及 [5.0]( https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html ) 两个协议。 |
| |
| ## 属性 |
| |
| | 名称 | 类型 | 必选项 | 描述 | |
| | -------------- | ------- | ----- | ------------------------------------------------------ | |
| | protocol_name | string | 是 | 协议名称,正常情况下应为 `MQTT`。 | |
| | protocol_level | integer | 是 | 协议级别,MQTT `3.1.*` 为 `4`,MQTT `5.0` 应是`5`。 | |
| |
| ## 启用插件 |
| |
| 为了启用该插件,需要先在配置文件(`./conf/config.yaml`)中加载 `stream_proxy` 相关配置。以下配置代表监听 `9100` TCP 端口: |
| |
| ```yaml title="./conf/config.yaml" |
| ... |
| router: |
| http: 'radixtree_uri' |
| ssl: 'radixtree_sni' |
| stream_proxy: # TCP/UDP proxy |
| tcp: # TCP proxy port list |
| - 9100 |
| dns_resolver: |
| ... |
| ``` |
| |
| 现在你可以将请求发送到 `9100` 端口。 |
| |
| 你可以创建一个 stream 路由并启用 `mqtt-proxy` 插件。 |
| |
| :::note |
| |
| 您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: |
| |
| ```bash |
| admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') |
| ``` |
| |
| ::: |
| |
| ```shell |
| curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \ |
| -H "X-API-KEY: $admin_key" -X PUT -d ' |
| { |
| "plugins": { |
| "mqtt-proxy": { |
| "protocol_name": "MQTT", |
| "protocol_level": 4 |
| } |
| }, |
| "upstream": { |
| "type": "roundrobin", |
| "nodes": [{ |
| "host": "127.0.0.1", |
| "port": 1980, |
| "weight": 1 |
| }] |
| } |
| }' |
| ``` |
| |
| 如果你在 macOS 中使用 Docker,则 `host.docker.internal` 是 `host` 的正确属性。 |
| |
| 该插件暴露了一个变量 `mqtt_client_id`,你可以使用它来通过客户端 ID 进行负载均衡。比如: |
| |
| ```shell |
| curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \ |
| -H "X-API-KEY: $admin_key" -X PUT -d ' |
| { |
| "plugins": { |
| "mqtt-proxy": { |
| "protocol_name": "MQTT", |
| "protocol_level": 4 |
| } |
| }, |
| "upstream": { |
| "type": "chash", |
| "key": "mqtt_client_id", |
| "nodes": [ |
| { |
| "host": "127.0.0.1", |
| "port": 1995, |
| "weight": 1 |
| }, |
| { |
| "host": "127.0.0.2", |
| "port": 1995, |
| "weight": 1 |
| } |
| ] |
| } |
| }' |
| ``` |
| |
| 不同客户端 ID 的 MQTT 连接将通过一致性哈希算法被转发到不同的节点。如果客户端 ID 为空,将会通过客户端 IP 进行均衡。 |
| |
| ## 使用 mqtt-proxy 插件启用 mTLS |
| |
| Stream 代理可以使用 TCP 连接并且支持 TLS。请参考 [如何通过 tcp 连接接受 tls](../stream-proxy.md/#accept-tls-over-tcp-connection) 打开启用了 TLS 的 stream 代理。 |
| |
| `mqtt-proxy` 插件通过 Stream 代理的指定端口的 TCP 通信启用,如果 `tls` 设置为 `true`,则还要求客户端通过 TLS 进行身份验证。 |
| |
| 配置 `ssl` 提供 CA 证书和服务器证书,以及 SNI 列表。使用 `ssl` 保护 `stream_routes` 的步骤等同于 [protect Routes](../mtls.md/#protect-route)。 |
| |
| ### 创建 stream_route 并配置 mqtt-proxy 插件和 mTLS |
| |
| 通过以下示例可以创建一个配置了 `mqtt-proxy` 插件的 `stream_route`,需要提供 CA 证书、客户端证书和客户端密钥(对于不受主机信任的自签名证书,请使用 -k 选项): |
| |
| ```shell |
| curl 127.0.0.1:9180/apisix/admin/stream_routes/1 \ |
| -H "X-API-KEY: $admin_key" -X PUT -d ' |
| { |
| "plugins": { |
| "mqtt-proxy": { |
| "protocol_name": "MQTT", |
| "protocol_level": 4 |
| } |
| }, |
| "sni": "${your_sni_name}", |
| "upstream": { |
| "nodes": { |
| "127.0.0.1:1980": 1 |
| }, |
| "type": "roundrobin" |
| } |
| }' |
| ``` |
| |
| :::note 注意 |
| |
| `sni` 名称必须与提供的 CA 和服务器证书创建的 SSL 对象的一个或多个 SNI 匹配。 |
| |
| ::: |
| |
| ## 删除插件 |
| |
| 当你需要删除该插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务: |
| |
| ```shell |
| curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \ |
| -H "X-API-KEY: $admin_key" -X DELETE |
| ``` |