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


##########
docs/en/latest/plugins/limit-conn.md:
##########
@@ -1567,3 +1567,153 @@ Response: 429
 Response: 200
 Response: 200
 ```
+
+### Apply Rate Limiting in Stream Proxy
+
+The `limit-conn` Plugin can also be used on a [stream 
Route](../stream-proxy.md) to limit the number of concurrent TCP connections.
+
+The following example demonstrates how to rate limit TCP connections by 
`remote_addr`, with example connection and burst thresholds.
+
+:::note
+
+When `key_type` is `var` (the default), `key` is resolved as an [NGINX stream 
module variable](https://nginx.org/en/docs/stream/ngx_stream_core_module.html). 
It is not limited to `remote_addr` or `server_addr`: any variable available in 
the stream context, such as `server_port`, can be used.
+
+:::
+
+Create a stream Route with `limit-conn` Plugin as such:
+
+<Tabs groupId="api">
+<TabItem value="admin-api" label="Admin API">
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "limit-conn-stream-route",
+    "plugins": {
+      "limit-conn": {
+        "conn": 2,
+        "burst": 1,
+        "default_conn_delay": 0.1,
+        "key_type": "var",
+        "key": "remote_addr"
+      }
+    },
+    "upstream": {
+      "type": "roundrobin",
+      "nodes": {
+        "127.0.0.1:1995": 1

Review Comment:
   The example is not runnable as written because it does not start a TCP 
service on `127.0.0.1:1995`. It also depends on stream mode and a TCP listener 
on port `9100`, but that prerequisite is only discoverable by leaving this 
section. Could you state the listener prerequisite here and provide a reachable 
upstream or the commands needed to create one? The Ingress example has the same 
issue because `tcp-echo.aic.svc` is not defined by the manifest.



##########
docs/en/latest/plugins/limit-conn.md:
##########
@@ -1567,3 +1567,153 @@ Response: 429
 Response: 200
 Response: 200
 ```
+
+### Apply Rate Limiting in Stream Proxy
+
+The `limit-conn` Plugin can also be used on a [stream 
Route](../stream-proxy.md) to limit the number of concurrent TCP connections.
+
+The following example demonstrates how to rate limit TCP connections by 
`remote_addr`, with example connection and burst thresholds.
+
+:::note
+
+When `key_type` is `var` (the default), `key` is resolved as an [NGINX stream 
module variable](https://nginx.org/en/docs/stream/ngx_stream_core_module.html). 
It is not limited to `remote_addr` or `server_addr`: any variable available in 
the stream context, such as `server_port`, can be used.
+
+:::
+
+Create a stream Route with `limit-conn` Plugin as such:
+
+<Tabs groupId="api">
+<TabItem value="admin-api" label="Admin API">
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "limit-conn-stream-route",
+    "plugins": {
+      "limit-conn": {
+        "conn": 2,
+        "burst": 1,
+        "default_conn_delay": 0.1,
+        "key_type": "var",
+        "key": "remote_addr"
+      }
+    },
+    "upstream": {
+      "type": "roundrobin",
+      "nodes": {
+        "127.0.0.1:1995": 1
+      }
+    }
+  }'
+```
+
+</TabItem>
+<TabItem value="adc" label="ADC">
+
+```yaml title="adc.yaml"
+services:
+  - name: tcp-echo-service
+    upstream:
+      name: default
+      scheme: tcp
+      nodes:
+        - host: 127.0.0.1
+          port: 1995
+          weight: 1
+    stream_routes:
+      - name: limit-conn-stream-route
+        server_port: 9100
+        plugins:
+          limit-conn:
+            conn: 2
+            burst: 1
+            default_conn_delay: 0.1
+            key_type: var
+            key: remote_addr
+```
+
+Synchronize the configuration to the gateway:
+
+```shell
+adc sync -f adc.yaml
+```
+
+</TabItem>
+<TabItem value="ingress" label="Ingress Controller">
+
+<Tabs groupId="k8s-api">
+<TabItem value="gateway-api" label="Gateway API">
+
+:::info
+
+Attaching L4 Plugins is currently not supported with Gateway API. This example 
cannot be completed with Gateway API.

Review Comment:
   This is no longer accurate for the current released controller. APISIX 
Ingress Controller 2.2.0 introduced `apisix.apache.org/v1alpha1` 
`L4RoutePolicy`, which attaches stream plugins such as `limit-conn` to 
`TCPRoute`, `UDPRoute`, and `TLSRoute`. Please replace this callout with a 
`TCPRoute` plus `L4RoutePolicy` example, or qualify the limitation to 
controller versions before 2.2.0.



##########
docs/en/latest/plugins/limit-conn.md:
##########
@@ -1567,3 +1567,153 @@ Response: 429
 Response: 200
 Response: 200
 ```
+
+### Apply Rate Limiting in Stream Proxy
+
+The `limit-conn` Plugin can also be used on a [stream 
Route](../stream-proxy.md) to limit the number of concurrent TCP connections.
+
+The following example demonstrates how to rate limit TCP connections by 
`remote_addr`, with example connection and burst thresholds.
+
+:::note
+
+When `key_type` is `var` (the default), `key` is resolved as an [NGINX stream 
module variable](https://nginx.org/en/docs/stream/ngx_stream_core_module.html). 
It is not limited to `remote_addr` or `server_addr`: any variable available in 
the stream context, such as `server_port`, can be used.

Review Comment:
   The stream plugin has a distinct, smaller schema: `conn`, `burst`, 
`default_conn_delay`, `only_use_default_delay`, `key`, and `key_type`; `conn` 
and `burst` are integers. The page’s existing Attributes table describes the 
HTTP plugin and includes HTTP-only fields such as Redis policies, `rules`, 
degradation, and custom HTTP rejection fields. Adding a stream example without 
separating or explicitly scoping those attributes can lead readers to apply 
unsupported fields to stream routes. Could this PR add a separate stream 
attribute table or clearly qualify the existing table?



##########
docs/en/latest/plugins/limit-conn.md:
##########
@@ -1567,3 +1567,153 @@ Response: 429
 Response: 200
 Response: 200
 ```
+
+### Apply Rate Limiting in Stream Proxy
+
+The `limit-conn` Plugin can also be used on a [stream 
Route](../stream-proxy.md) to limit the number of concurrent TCP connections.
+
+The following example demonstrates how to rate limit TCP connections by 
`remote_addr`, with example connection and burst thresholds.
+
+:::note
+
+When `key_type` is `var` (the default), `key` is resolved as an [NGINX stream 
module variable](https://nginx.org/en/docs/stream/ngx_stream_core_module.html). 
It is not limited to `remote_addr` or `server_addr`: any variable available in 
the stream context, such as `server_port`, can be used.
+
+:::
+
+Create a stream Route with `limit-conn` Plugin as such:
+
+<Tabs groupId="api">
+<TabItem value="admin-api" label="Admin API">
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/stream_routes"; -X PUT \
+  -H "X-API-KEY: ${admin_key}" \
+  -d '{
+    "id": "limit-conn-stream-route",
+    "plugins": {
+      "limit-conn": {
+        "conn": 2,
+        "burst": 1,
+        "default_conn_delay": 0.1,
+        "key_type": "var",
+        "key": "remote_addr"
+      }
+    },
+    "upstream": {
+      "type": "roundrobin",
+      "nodes": {
+        "127.0.0.1:1995": 1
+      }
+    }
+  }'
+```
+
+</TabItem>
+<TabItem value="adc" label="ADC">
+
+```yaml title="adc.yaml"
+services:
+  - name: tcp-echo-service
+    upstream:
+      name: default
+      scheme: tcp
+      nodes:
+        - host: 127.0.0.1
+          port: 1995
+          weight: 1
+    stream_routes:
+      - name: limit-conn-stream-route
+        server_port: 9100
+        plugins:
+          limit-conn:
+            conn: 2
+            burst: 1
+            default_conn_delay: 0.1
+            key_type: var
+            key: remote_addr
+```
+
+Synchronize the configuration to the gateway:
+
+```shell
+adc sync -f adc.yaml
+```
+
+</TabItem>
+<TabItem value="ingress" label="Ingress Controller">
+
+<Tabs groupId="k8s-api">
+<TabItem value="gateway-api" label="Gateway API">
+
+:::info
+
+Attaching L4 Plugins is currently not supported with Gateway API. This example 
cannot be completed with Gateway API.
+
+:::
+
+</TabItem>
+<TabItem value="ingress" label="APISIX Ingress Controller">
+
+```yaml title="limit-conn-stream-ic.yaml"
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: aic
+  name: tcp-echo-service
+spec:
+  type: ExternalName
+  externalName: tcp-echo.aic.svc
+  ports:
+    - name: tcp-echo
+      port: 1995
+      targetPort: 1995
+---
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  namespace: aic
+  name: limit-conn-stream-route
+spec:
+  ingressClassName: apisix
+  stream:
+    - name: limit-conn-stream-route
+      protocol: TCP
+      match:
+        ingressPort: 9100
+      backend:
+        serviceName: tcp-echo-service
+        servicePort: 1995
+      plugins:
+        - name: limit-conn
+          enable: true
+          config:
+            conn: 2
+            burst: 1
+            default_conn_delay: 0.1
+            key_type: var
+            key: remote_addr
+```
+
+Apply the configuration:
+
+```shell
+kubectl apply -f limit-conn-stream-ic.yaml
+```
+
+</TabItem>
+</Tabs>
+
+</TabItem>
+</Tabs>
+
+❶ `key_type`: set to `var` to interpret `key` as a variable.
+
+❷ `key`: calculate rate limiting count by the connection's `remote_addr`.
+
+Open three concurrent TCP connections to the stream Route:
+
+```shell
+seq 1 3 | xargs -n1 -P3 -I{} bash -c 'echo "hello" | nc -w 1 127.0.0.1 9100'

Review Comment:
   With `conn: 2` and `burst: 1`, APISIX permits three concurrent connections; 
rejection starts with the fourth. This command opens only three, and the short 
`echo | nc -w 1` sessions may not overlap reliably, so it cannot verify the 
following rejection claim. Please use a deterministic test, such as `conn: 1`, 
`burst: 0`, holding one connection open while a second is reset, then retrying 
after the first closes. The documentation should also show the actual observed 
output.



##########
t/stream-plugin/limit-conn.t:
##########
@@ -339,3 +339,51 @@ GET /test_concurrency
 --- error_log
 The value of the configured key is empty, use client IP instead
 --- stream_enable
+
+
+
+=== TEST 11: key is a var other than remote_addr/server_addr
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "limit-conn": {
+                            "conn": 2,
+                            "burst": 1,
+                            "default_conn_delay": 0.1,
+                            "key": "server_port"
+                        }
+                    },
+                    "upstream_id": "1"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 12: exceeding the burst when keyed by a non-address var
+--- request
+GET /test_concurrency
+--- response_body
+200
+200
+200

Review Comment:
   This result does not prove that `server_port` was resolved and used as the 
limiter key. If lookup failed, the implementation would fall back to 
`remote_addr` and produce the same three-success/two-rejection pattern. Please 
assert that the logged limit key contains the expected listener port (the 
existing remote-address test uses this pattern) and assert that `The value of 
the configured key is empty` is absent.



-- 
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