mqtt-proxy

描述

通过 mqtt-proxy 插件可以使用 MQTT 的 client_id 进行动态负载平衡。它仅适用于 stream 模式。

这个插件支持 MQTT 3.1.*5.0 两个协议。

属性

名称类型必选项描述
protocol_namestring协议名称,正常情况下应为 MQTT
protocol_levelinteger协议级别,MQTT 3.1.*4,MQTT 5.0 应是5

启用插件

为了启用该插件,需要先在配置文件(./conf/config.yaml)中加载 stream_proxy 相关配置。以下配置代表监听 9100 TCP 端口:

./conf/config.yaml

  1. ...
  2. router:
  3. http: 'radixtree_uri'
  4. ssl: 'radixtree_sni'
  5. stream_proxy: # TCP/UDP proxy
  6. tcp: # TCP proxy port list
  7. - 9100
  8. dns_resolver:
  9. ...

现在你可以将请求发送到 9100 端口。

你可以创建一个 stream 路由并启用 mqtt-proxy 插件。

mqtt-proxy - 图1note

您可以这样从 config.yaml 中获取 admin_key 并存入环境变量:

  1. admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
  1. curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \
  2. -H "X-API-KEY: $admin_key" -X PUT -d '
  3. {
  4. "plugins": {
  5. "mqtt-proxy": {
  6. "protocol_name": "MQTT",
  7. "protocol_level": 4
  8. }
  9. },
  10. "upstream": {
  11. "type": "roundrobin",
  12. "nodes": [{
  13. "host": "127.0.0.1",
  14. "port": 1980,
  15. "weight": 1
  16. }]
  17. }
  18. }'

如果你在 macOS 中使用 Docker,则 host.docker.internalhost 的正确属性。

该插件暴露了一个变量 mqtt_client_id,你可以使用它来通过客户端 ID 进行负载均衡。比如:

  1. curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \
  2. -H "X-API-KEY: $admin_key" -X PUT -d '
  3. {
  4. "plugins": {
  5. "mqtt-proxy": {
  6. "protocol_name": "MQTT",
  7. "protocol_level": 4
  8. }
  9. },
  10. "upstream": {
  11. "type": "chash",
  12. "key": "mqtt_client_id",
  13. "nodes": [
  14. {
  15. "host": "127.0.0.1",
  16. "port": 1995,
  17. "weight": 1
  18. },
  19. {
  20. "host": "127.0.0.2",
  21. "port": 1995,
  22. "weight": 1
  23. }
  24. ]
  25. }
  26. }'

不同客户端 ID 的 MQTT 连接将通过一致性哈希算法被转发到不同的节点。如果客户端 ID 为空,将会通过客户端 IP 进行均衡。

使用 mqtt-proxy 插件启用 mTLS

Stream 代理可以使用 TCP 连接并且支持 TLS。请参考 如何通过 tcp 连接接受 tls 打开启用了 TLS 的 stream 代理。

mqtt-proxy 插件通过 Stream 代理的指定端口的 TCP 通信启用,如果 tls 设置为 true,则还要求客户端通过 TLS 进行身份验证。

配置 ssl 提供 CA 证书和服务器证书,以及 SNI 列表。使用 ssl 保护 stream_routes 的步骤等同于 protect Routes

创建 stream_route 并配置 mqtt-proxy 插件和 mTLS

通过以下示例可以创建一个配置了 mqtt-proxy 插件的 stream_route,需要提供 CA 证书、客户端证书和客户端密钥(对于不受主机信任的自签名证书,请使用 -k 选项):

  1. curl 127.0.0.1:9180/apisix/admin/stream_routes/1 \
  2. -H "X-API-KEY: $admin_key" -X PUT -d '
  3. {
  4. "plugins": {
  5. "mqtt-proxy": {
  6. "protocol_name": "MQTT",
  7. "protocol_level": 4
  8. }
  9. },
  10. "sni": "${your_sni_name}",
  11. "upstream": {
  12. "nodes": {
  13. "127.0.0.1:1980": 1
  14. },
  15. "type": "roundrobin"
  16. }
  17. }'
mqtt-proxy - 图2注意

sni 名称必须与提供的 CA 和服务器证书创建的 SSL 对象的一个​​或多个 SNI 匹配。

删除插件

当你需要删除该插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务:

  1. curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \
  2. -H "X-API-KEY: $admin_key" -X DELETE