kayx23 commented on code in PR #13310:
URL: https://github.com/apache/apisix/pull/13310#discussion_r3198848229


##########
docs/en/latest/plugins/mqtt-proxy.md:
##########
@@ -70,101 +73,409 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' 
conf/config.yaml | sed 's/"/
 
 :::
 
+### Proxy to a MQTT Broker
+
+The following example demonstrates how you can configure a stream Route to 
proxy traffic to a hosted MQTT server and verify that APISIX can proxy MQTT 
messages successfully.
+
+Create a stream Route to the MQTT server and configure the `mqtt-proxy` Plugin:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
+
+<TabItem value="admin-api">
+
 ```shell
-curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 -H "X-API-KEY: 
$admin_key" -X PUT -d '
-{
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "mqtt-route-proxy",
     "plugins": {
-        "mqtt-proxy": {
-            "protocol_name": "MQTT",
-            "protocol_level": 4
-        }
+      "mqtt-proxy": {
+        "protocol_name": "MQTT",
+        "protocol_level": 4
+      }
     },
     "upstream": {
-        "type": "roundrobin",
-        "nodes": [{
-            "host": "127.0.0.1",
-            "port": 1980,
-            "weight": 1
-        }]
+      "type": "roundrobin",
+      "nodes": [
+        {
+          "host": "test.mosquitto.org",
+          "port": 1883,
+          "weight": 1
+        }
+      ]
     }
-}'
+  }'
 ```
 
-:::note
+</TabItem>
+
+<TabItem value="adc">
+
+```yaml title="adc.yaml"
+services:
+  - name: mqtt-service
+    upstream:
+      name: default
+      scheme: tcp
+      nodes:
+        - host: test.mosquitto.org
+          port: 1883
+          weight: 1
+    stream_routes:
+      - name: mqtt-route
+        server_port: 9100
+        plugins:
+          mqtt-proxy:
+            protocol_name: MQTT
+            protocol_level: 4
+```
+
+Synchronize the configuration to the gateway:
+
+```shell
+adc sync -f adc.yaml
+```
 
-If you are using Docker in macOS, then `host.docker.internal` is the right 
parameter for the `host` attribute.
+</TabItem>
+
+<TabItem value="aic">
+
+<Tabs
+groupId="k8s-api"
+defaultValue="gateway-api"
+values={[
+{label: 'Gateway API', value: 'gateway-api'},
+{label: 'APISIX CRD', value: 'apisix-crd'}
+]}>
+
+<TabItem value="gateway-api">
+
+:::info
+
+Attaching L4 plugins is currently not supported with Gateway API. At the 
moment, this example cannot be completed with Gateway API.
 
 :::
 
-This Plugin exposes a variable `mqtt_client_id` which can be used for load 
balancing as shown below:
+</TabItem>
+
+<TabItem value="apisix-crd">
+
+Use APISIX CRD to attach the `mqtt-proxy` Plugin to the stream Route:
+
+```yaml title="mqtt-proxy-ic.yaml"
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: aic
+  name: mqtt-broker
+spec:
+  type: ExternalName
+  externalName: test.mosquitto.org
+  ports:
+    - name: mqtt
+      port: 1883
+      targetPort: 1883
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  namespace: aic
+  name: mqtt-route
+spec:
+  ingressClassName: apisix
+  stream:
+    - name: mqtt-route
+      protocol: TCP
+      match:
+        ingressPort: 9100
+      backend:
+        serviceName: mqtt-broker
+        servicePort: 1883
+      plugins:
+        - name: mqtt-proxy
+          enable: true
+          config:
+            protocol_name: MQTT
+            protocol_level: 4
+```
+
+Apply the configuration:
+
+```shell
+kubectl apply -f mqtt-proxy-ic.yaml
+```
+
+</TabItem>
+
+</Tabs>
+
+</TabItem>
+
+</Tabs>
+
+Open two terminal sessions. In the first one, subscribe to the test topic:
+
+```shell
+mosquitto_sub -h test.mosquitto.org -p 1883 -t "test/apisix"
+```
+
+In the other one, publish a sample message to the created Route:
+
+```shell
+mosquitto_pub -h 127.0.0.1 -p 9100 -t "test/apisix" -m "Hello APISIX"
+```
+
+You should see the message `Hello APISIX` in the first terminal.
+
+### Load Balance MQTT Traffic
+
+The following example demonstrates how you can configure a stream Route to 
load balance MQTT traffic to different MQTT servers.
+
+When the Plugin is enabled, it registers a variable `mqtt_client_id` which can 
be used for load balancing. MQTT connections with different client IDs will be 
forwarded to different upstream nodes based on the consistent hash algorithm. 
If the client ID is missing, the client IP will be used instead.
+
+Create a stream Route to two MQTT servers and configure the `mqtt-proxy` 
Plugin:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
+
+<TabItem value="admin-api">
 
 ```shell
-curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 -H "X-API-KEY: 
$admin_key" -X PUT -d '
-{
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "mqtt-route-lb",
     "plugins": {
-        "mqtt-proxy": {
-            "protocol_name": "MQTT",
-            "protocol_level": 4
-        }
+      "mqtt-proxy": {
+        "protocol_name": "MQTT",
+        "protocol_level": 4
+      }
     },
     "upstream": {
-        "type": "chash",
-        "key": "mqtt_client_id",
-        "nodes": [
+      "type": "chash",
+      "key": "mqtt_client_id",
+      "nodes": [
         {
-            "host": "127.0.0.1",
-            "port": 1995,
-            "weight": 1
+          "host": "test.mosquitto.org",
+          "port": 1883,
+          "weight": 1
         },
         {
-            "host": "127.0.0.2",
-            "port": 1995,
-            "weight": 1
+          "host": "broker.mqtt.cool",
+          "port": 1883,
+          "weight": 1
         }
-        ]
+      ]
     }
-}'
+  }'
+```
+
+</TabItem>
+
+<TabItem value="adc">
+
+```yaml title="adc.yaml"
+services:
+  - name: mqtt-service
+    upstream:
+      name: default
+      scheme: tcp
+      type: chash
+      key: mqtt_client_id
+      nodes:
+        - host: test.mosquitto.org
+          port: 1883
+          weight: 1
+        - host: broker.mqtt.cool
+          port: 1883
+          weight: 1
+    stream_routes:
+      - name: mqtt-route
+        server_port: 9100
+        plugins:
+          mqtt-proxy:
+            protocol_name: MQTT
+            protocol_level: 4
+```
+
+Synchronize the configuration to the gateway:
+
+```shell
+adc sync -f adc.yaml
 ```
 
-MQTT connections with different client ID will be forwarded to different nodes 
based on the consistent hash algorithm. If client ID is missing, client IP is 
used instead for load balancing.
+</TabItem>
+
+<TabItem value="aic">
+
+<Tabs
+groupId="k8s-api"
+defaultValue="gateway-api"
+values={[
+{label: 'Gateway API', value: 'gateway-api'},
+{label: 'APISIX CRD', value: 'apisix-crd'}
+]}>
+
+<TabItem value="gateway-api">
+
+:::info
+
+Attaching L4 plugins is currently not supported with Gateway API. At the 
moment, this example cannot be completed with Gateway API.
+
+:::
+
+</TabItem>
+
+<TabItem value="apisix-crd">
+
+```yaml title="mqtt-proxy-ic.yaml"
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: aic
+  name: mqtt-brokers
+spec:
+  ports:
+    - name: mqtt
+      port: 1883
+      protocol: TCP
+---
+apiVersion: discovery.k8s.io/v1
+kind: EndpointSlice
+metadata:
+  namespace: aic
+  name: mqtt-brokers-1
+  labels:
+    kubernetes.io/service-name: mqtt-brokers
+addressType: FQDN
+ports:
+  - name: mqtt
+    protocol: TCP
+    port: 1883
+endpoints:
+  - addresses:
+      - test.mosquitto.org
+  - addresses:
+      - broker.mqtt.cool
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  namespace: aic
+  name: mqtt-brokers
+spec:
+  ingressClassName: apisix
+  loadbalancer:
+    type: chash
+    key: mqtt_client_id
+    hashOn: vars
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  namespace: aic
+  name: mqtt-route
+spec:
+  ingressClassName: apisix
+  stream:
+    - name: mqtt-route
+      protocol: TCP
+      match:
+        ingressPort: 9100
+      backend:
+        serviceName: mqtt-brokers
+        servicePort: 1883
+      plugins:
+        - name: mqtt-proxy
+          enable: true
+          config:
+            protocol_name: MQTT
+            protocol_level: 4
+```
+
+Apply the configuration:
+
+```shell
+kubectl apply -f mqtt-proxy-ic.yaml
+```

Review Comment:
   This conclusion is stronger than what the example actually proves. With 
`chash` on `mqtt_client_id`, each fixed client ID deterministically sticks to 
one broker. Sending one message with `client-1` and one with `client-2` can 
demonstrate sticky routing by client ID, but it does not reliably verify 
distribution across both brokers on every run. Please soften the wording here 
(same issue in the ZH file).



##########
docs/zh/latest/plugins/mqtt-proxy.md:
##########
@@ -71,105 +73,409 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' 
conf/config.yaml | sed 's/"/
 
 :::
 
+### 代理到 MQTT Broker
+
+以下示例演示如何配置流式路由,将流量代理到托管的 MQTT 服务器,并验证 APISIX 能够成功代理 MQTT 消息。
+
+创建流式路由并配置 `mqtt-proxy` 插件:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
+
+<TabItem value="admin-api">
+
 ```shell
-curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \
--H "X-API-KEY: $admin_key" -X PUT -d '
-{
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "mqtt-route-proxy",
     "plugins": {
-        "mqtt-proxy": {
-            "protocol_name": "MQTT",
-            "protocol_level": 4
-        }
+      "mqtt-proxy": {
+        "protocol_name": "MQTT",
+        "protocol_level": 4
+      }
     },
     "upstream": {
-        "type": "roundrobin",
-        "nodes": [{
-            "host": "127.0.0.1",
-            "port": 1980,
-            "weight": 1
-        }]
+      "type": "roundrobin",
+      "nodes": [
+        {
+          "host": "test.mosquitto.org",
+          "port": 1883,
+          "weight": 1
+        }
+      ]
     }
-}'
+  }'
+```
+
+</TabItem>
+
+<TabItem value="adc">
+
+```yaml title="adc.yaml"
+services:
+  - name: mqtt-service
+    upstream:
+      name: default
+      scheme: tcp
+      nodes:
+        - host: test.mosquitto.org
+          port: 1883
+          weight: 1
+    stream_routes:
+      - name: mqtt-route
+        server_port: 9100
+        plugins:
+          mqtt-proxy:
+            protocol_name: MQTT
+            protocol_level: 4
+```
+
+将配置同步到网关:
+
+```shell
+adc sync -f adc.yaml
+```
+
+</TabItem>
+
+<TabItem value="aic">
+
+<Tabs
+groupId="k8s-api"
+defaultValue="gateway-api"
+values={[
+{label: 'Gateway API', value: 'gateway-api'},
+{label: 'APISIX CRD', value: 'apisix-crd'}
+]}>
+
+<TabItem value="gateway-api">
+
+:::info
+
+Gateway API 目前不支持配置 L4 插件。此示例暂时无法通过 Gateway API 完成。
+
+:::
+
+</TabItem>
+
+<TabItem value="apisix-crd">
+
+使用 APISIX CRD 将 `mqtt-proxy` 插件配置到流式路由:
+
+```yaml title="mqtt-proxy-ic.yaml"
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: aic
+  name: mqtt-broker
+spec:
+  type: ExternalName
+  externalName: test.mosquitto.org
+  ports:
+    - name: mqtt
+      port: 1883
+      targetPort: 1883
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  namespace: aic
+  name: mqtt-route
+spec:
+  ingressClassName: apisix
+  stream:
+    - name: mqtt-route
+      protocol: TCP
+      match:
+        ingressPort: 9100
+      backend:
+        serviceName: mqtt-broker
+        servicePort: 1883
+      plugins:
+        - name: mqtt-proxy
+          enable: true
+          config:
+            protocol_name: MQTT
+            protocol_level: 4
 ```
 
-如果你在 macOS 中使用 Docker,则 `host.docker.internal` 是 `host` 的正确属性。
+应用配置:
+
+```shell
+kubectl apply -f mqtt-proxy-ic.yaml
+```
+
+</TabItem>
+
+</Tabs>
+
+</TabItem>
+
+</Tabs>
+
+打开两个终端会话。在第一个终端中,订阅测试主题:
+
+```shell
+mosquitto_sub -h test.mosquitto.org -p 1883 -t "test/apisix"
+```
+
+在另一个终端中,向创建的路由发布示例消息:
+
+```shell
+mosquitto_pub -h 127.0.0.1 -p 9100 -t "test/apisix" -m "Hello APISIX"
+```
+
+你应该在第一个终端中看到消息 `Hello APISIX`。
+
+### 对 MQTT 流量进行负载均衡
+
+以下示例演示如何配置流式路由,将 MQTT 流量负载均衡到不同的 MQTT 服务器。
+
+启用该插件后,它会注册一个变量 `mqtt_client_id`,可用于负载均衡。不同客户端 ID 的 MQTT 
连接将根据一致性哈希算法转发到不同的上游节点。如果客户端 ID 缺失,则使用客户端 IP 代替。
+
+创建流式路由,并将 `mqtt-proxy` 插件配置为指向两个 MQTT 服务器:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
 
-该插件暴露了一个变量 `mqtt_client_id`,你可以使用它来通过客户端 ID 进行负载均衡。比如:
+<TabItem value="admin-api">
 
 ```shell
-curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 \
--H "X-API-KEY: $admin_key" -X PUT -d '
-{
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "mqtt-route-lb",
     "plugins": {
-        "mqtt-proxy": {
-            "protocol_name": "MQTT",
-            "protocol_level": 4
-        }
+      "mqtt-proxy": {
+        "protocol_name": "MQTT",
+        "protocol_level": 4
+      }
     },
     "upstream": {
-        "type": "chash",
-        "key": "mqtt_client_id",
-        "nodes": [
+      "type": "chash",
+      "key": "mqtt_client_id",
+      "nodes": [
         {
-            "host": "127.0.0.1",
-            "port": 1995,
-            "weight": 1
+          "host": "test.mosquitto.org",
+          "port": 1883,
+          "weight": 1
         },
         {
-            "host": "127.0.0.2",
-            "port": 1995,
-            "weight": 1
+          "host": "broker.mqtt.cool",
+          "port": 1883,
+          "weight": 1
         }
-        ]
+      ]
     }
-}'
+  }'
+```
+
+</TabItem>
+
+<TabItem value="adc">
+
+```yaml title="adc.yaml"
+services:
+  - name: mqtt-service
+    upstream:
+      name: default
+      scheme: tcp
+      type: chash
+      key: mqtt_client_id
+      nodes:
+        - host: test.mosquitto.org
+          port: 1883
+          weight: 1
+        - host: broker.mqtt.cool
+          port: 1883
+          weight: 1
+    stream_routes:
+      - name: mqtt-route
+        server_port: 9100
+        plugins:
+          mqtt-proxy:
+            protocol_name: MQTT
+            protocol_level: 4
 ```
 
-不同客户端 ID 的 MQTT 连接将通过一致性哈希算法被转发到不同的节点。如果客户端 ID 为空,将会通过客户端 IP 进行均衡。
+将配置同步到网关:
 
-## 使用 mqtt-proxy 插件启用 mTLS
+```shell
+adc sync -f adc.yaml
+```
+
+</TabItem>
 
-Stream 代理可以使用 TCP 连接并且支持 TLS。请参考 [如何通过 tcp 连接接受 
tls](../stream-proxy.md/#accept-tls-over-tcp-connection) 打开启用了 TLS 的 stream 代理。
+<TabItem value="aic">
 
-`mqtt-proxy` 插件通过 Stream 代理的指定端口的 TCP 通信启用,如果 `tls` 设置为 `true`,则还要求客户端通过 TLS 
进行身份验证。
+<Tabs
+groupId="k8s-api"
+defaultValue="gateway-api"
+values={[
+{label: 'Gateway API', value: 'gateway-api'},
+{label: 'APISIX CRD', value: 'apisix-crd'}
+]}>
 
-配置 `ssl` 提供 CA 证书和服务器证书,以及 SNI 列表。使用 `ssl` 保护 `stream_routes` 的步骤等同于 [protect 
Routes](../mtls.md/#protect-route)。
+<TabItem value="gateway-api">
 
-### 创建 stream_route 并配置 mqtt-proxy 插件和 mTLS
+:::info
 
-通过以下示例可以创建一个配置了 `mqtt-proxy` 插件的 `stream_route`,需要提供 CA 
证书、客户端证书和客户端密钥(对于不受主机信任的自签名证书,请使用 -k 选项):
+Gateway API 目前不支持配置 L4 插件。此示例暂时无法通过 Gateway API 完成。
+
+:::
+
+</TabItem>
+
+<TabItem value="apisix-crd">
+
+```yaml title="mqtt-proxy-ic.yaml"
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: aic
+  name: mqtt-brokers
+spec:
+  ports:
+    - name: mqtt
+      port: 1883
+      protocol: TCP
+---
+apiVersion: discovery.k8s.io/v1
+kind: EndpointSlice
+metadata:
+  namespace: aic
+  name: mqtt-brokers-1
+  labels:
+    kubernetes.io/service-name: mqtt-brokers
+addressType: FQDN
+ports:
+  - name: mqtt
+    protocol: TCP
+    port: 1883
+endpoints:
+  - addresses:
+      - test.mosquitto.org
+  - addresses:
+      - broker.mqtt.cool
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  namespace: aic
+  name: mqtt-brokers
+spec:
+  ingressClassName: apisix
+  loadbalancer:
+    type: chash
+    key: mqtt_client_id
+    hashOn: vars
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  namespace: aic
+  name: mqtt-route
+spec:
+  ingressClassName: apisix
+  stream:
+    - name: mqtt-route
+      protocol: TCP
+      match:
+        ingressPort: 9100
+      backend:
+        serviceName: mqtt-brokers
+        servicePort: 1883
+      plugins:
+        - name: mqtt-proxy

Review Comment:
   这里的结论比示例实际能证明的内容更强。对 `mqtt_client_id` 使用 `chash` 时,每个固定的 client ID 
都会稳定地命中同一个 broker。用 `client-1` 和 `client-2` 各发一条消息,最多只能说明它展示了基于 client ID 
的粘性路由,不能在每次运行中都可靠地证明消息一定会分布到两个 broker。建议把这里的表述写得更保守一些。



##########
docs/zh/latest/plugins/mqtt-proxy.md:
##########
@@ -71,105 +73,409 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' 
conf/config.yaml | sed 's/"/
 
 :::
 
+### 代理到 MQTT Broker
+
+以下示例演示如何配置流式路由,将流量代理到托管的 MQTT 服务器,并验证 APISIX 能够成功代理 MQTT 消息。
+
+创建流式路由并配置 `mqtt-proxy` 插件:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
+

Review Comment:
   这些 Admin API 示例使用的是 `PUT /apisix/admin/stream_routes`,并把路由 `id` 放在请求体中;但仓库里 
stream route 的 Admin API 文档和实现都还是 `PUT /apisix/admin/stream_routes/{id}`。可参考 
`docs/zh/latest/admin-api.md` 和 `apisix/admin/stream_routes.lua`。请把本页中的 Admin 
API 示例改成带 `{id}` 的路径(ZH 文件里也有多处同样问题)。



##########
docs/en/latest/plugins/mqtt-proxy.md:
##########
@@ -70,101 +73,409 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' 
conf/config.yaml | sed 's/"/
 
 :::
 
+### Proxy to a MQTT Broker
+
+The following example demonstrates how you can configure a stream Route to 
proxy traffic to a hosted MQTT server and verify that APISIX can proxy MQTT 
messages successfully.
+
+Create a stream Route to the MQTT server and configure the `mqtt-proxy` Plugin:
+
+<Tabs
+groupId="api"
+defaultValue="admin-api"
+values={[
+{label: 'Admin API', value: 'admin-api'},
+{label: 'ADC', value: 'adc'},
+{label: 'Ingress Controller', value: 'aic'}
+]}>
+
+<TabItem value="admin-api">
+
 ```shell
-curl http://127.0.0.1:9180/apisix/admin/stream_routes/1 -H "X-API-KEY: 
$admin_key" -X PUT -d '
-{
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "mqtt-route-proxy",
     "plugins": {
-        "mqtt-proxy": {
-            "protocol_name": "MQTT",
-            "protocol_level": 4
-        }
+      "mqtt-proxy": {
+        "protocol_name": "MQTT",
+        "protocol_level": 4
+      }
     },
     "upstream": {

Review Comment:
   These Admin API examples use `PUT /apisix/admin/stream_routes` with the 
route `id` in the request body, but the stream route Admin API in this repo is 
documented and implemented as `PUT /apisix/admin/stream_routes/{id}`. See 
`docs/en/latest/admin-api.md` and `apisix/admin/stream_routes.lua`. Please 
update the Admin API examples in this doc (same issue appears multiple times, 
and also in the ZH file).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to