Copilot commented on code in PR #13216: URL: https://github.com/apache/apisix/pull/13216#discussion_r3090309315
########## docs/en/latest/plugins/limit-req.md: ########## @@ -31,55 +31,79 @@ description: The limit-req Plugin uses the leaky bucket algorithm to rate limit <link rel="canonical" href="https://docs.api7.ai/hub/limit-req" /> </head> +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + ## Description The `limit-req` Plugin uses the [leaky bucket](https://en.wikipedia.org/wiki/Leaky_bucket) algorithm to rate limit the number of the requests and allow for throttling. +## Local vs Redis Rate Limiting + +The `limit-req` Plugin supports two modes of rate limiting: + +* **Local rate limiting**: Limits are enforced independently on each gateway instance. Each instance maintains its own counters, so the effective limit is roughly (limit × number of instances) when traffic is spread across instances. This is the default when no `policy` is set or when `policy` is `local`. +* **Redis-based rate limiting**: Limits are shared across all gateway instances through Redis. All instances share the same quota, so the configured limit applies to all gateway instances. + ## Attributes -| Name | Type | Required | Default | Valid values | Description | -|-------------------|---------|----------|---------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| rate | integer | True | | > 0 | The maximum number of requests allowed per second. Requests exceeding the rate and below burst will be delayed. | -| burst | integer | True | | >= 0 | The number of requests allowed to be delayed per second for throttling. Requests exceeding the rate and burst will get rejected. | -| key_type | string | False | var | ["var", "var_combination"] | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. | -| key | string | True | remote_addr | | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. | -| rejected_code | integer | False | 503 | [200,...,599] | The HTTP status code returned when a request is rejected for exceeding the threshold. | -| rejected_msg | string | False | | non-empty | The response body returned when a request is rejected for exceeding the threshold. | -| nodelay | boolean | False | false | | If true, do not delay requests within the burst threshold. | -| allow_degradation | boolean | False | false | | If true, allow APISIX to continue handling requests without the Plugin when the Plugin or its dependencies become unavailable. | -| policy | string | False | local | ["local", "redis", "redis-cluster"] | The policy for rate limiting counter. If it is `local`, the counter is stored in memory locally. If it is `redis`, the counter is stored on a Redis instance. If it is `redis-cluster`, the counter is stored in a Redis cluster. | -| redis_host | string | False | | | The address of the Redis node. Required when `policy` is `redis`. | -| redis_port | integer | False | 6379 | [1,...] | The port of the Redis node when `policy` is `redis`. | -| redis_username | string | False | | | The username for Redis if Redis ACL is used. If you use the legacy authentication method `requirepass`, configure only the `redis_password`. Used when `policy` is `redis`. | -| redis_password | string | False | | | The password of the Redis node when `policy` is `redis` or `redis-cluster`. | -| redis_ssl | boolean | False | false | | If true, use SSL to connect to Redis cluster when `policy` is `redis`. | -| redis_ssl_verify | boolean | False | false | | If true, verify the server SSL certificate when `policy` is `redis`. | -| redis_database | integer | False | 0 | >= 0 | The database number in Redis when `policy` is `redis`. | -| redis_timeout | integer | False | 1000 | [1,...] | The Redis timeout value in milliseconds when `policy` is `redis` or `redis-cluster`. | -| redis_keepalive_timeout | integer | False | 10000 | ≥ 1000 | Keepalive timeout in milliseconds for redis when `policy` is `redis` or `redis-cluster`. | -| redis_keepalive_pool | integer | False | 100 | ≥ 1 | Keepalive pool size for redis when `policy` is `redis` or `redis-cluster`. | -| redis_cluster_nodes | array[string] | False | | | The list of the Redis cluster nodes with at least two addresses. Required when policy is redis-cluster. | -| redis_cluster_name | string | False | | | The name of the Redis cluster. Required when `policy` is `redis-cluster`. | -| redis_cluster_ssl | boolean | False | false | | If true, use SSL to connect to Redis cluster when `policy` is | -| redis_cluster_ssl_verify | boolean | False | false | | If true, verify the server SSL certificate when `policy` is `redis-cluster`. | +| Name | Type | Required | Default | Valid values | Description | +|------|------|----------|---------|--------------|-------------| +| rate | number | True | | > 0 | The maximum number of requests allowed per second. Requests exceeding the rate and below burst will be delayed. | +| burst | number | True | | >= 0 | The number of requests allowed to be delayed per second for throttling. Requests exceeding the rate and burst will get rejected. | +| key_type | string | False | var | ["var", "var_combination"] | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. | +| key | string | True | | | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. | Review Comment: The `key_type` description has a grammatical error (“interpreted a variable” / “interpreted as a combination…” is missing “as”). Please update these phrases (e.g., “interpreted as a variable”) to improve clarity. ```suggestion | key_type | string | False | var | ["var", "var_combination"] | The type of key. If the `key_type` is `var`, the `key` is interpreted as a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. | | key | string | True | | | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted as a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. | ``` ########## docs/en/latest/plugins/limit-req.md: ########## @@ -106,6 +131,169 @@ curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ }' ``` +</TabItem> + +<TabItem value="adc"> + +```yaml title="adc.yaml" +services: + - name: httpbin + routes: + - uris: + - /get + name: limit-req-route + plugins: + limit-req: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` + +Synchronize the configuration to the gateway: + +```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"> + +```yaml title="limit-req-ic.yaml" +apiVersion: v1 +kind: Service +metadata: + namespace: aic + name: httpbin-external-domain +spec: + type: ExternalName + externalName: httpbin.org +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: limit-req-plugin-config +spec: + plugins: + - name: limit-req + config: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: limit-req-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /get + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: limit-req-plugin-config + backendRefs: + - name: httpbin-external-domain + port: 80 +``` + +</TabItem> + +<TabItem value="apisix-crd"> + +```yaml title="limit-req-ic.yaml" +apiVersion: apisix.apache.org/v2 +kind: ApisixUpstream +metadata: + namespace: aic + name: httpbin-external-domain +spec: + ingressClassName: apisix + externalNodes: + - type: Domain + name: httpbin.org +--- +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + namespace: aic + name: limit-req-route +spec: + ingressClassName: apisix + http: + - name: limit-req-route + match: + paths: + - /get + methods: + - GET + upstreams: + - name: httpbin-external-domain + plugins: + - name: limit-req + config: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true +``` + +</TabItem> + +</Tabs> + +Apply the configuration: + +```shell +kubectl apply -f limit-req-ic.yaml +``` + +</TabItem> + +</Tabs> + +❶ `rate`: limit the QPS to 1. + +❷ `key`: set to `remote_addr` to apply rate limiting quota by remote address and consumer. Review Comment: In the “Apply Rate Limiting by Remote Address” example, this note says the `key` applies quota by remote address *and consumer*, but the configuration only uses `remote_addr` and does not involve consumer identity. Please adjust the wording to avoid implying consumer-based limiting here. ```suggestion ❷ `key`: set to `remote_addr` to apply rate limiting quota by remote address. ``` ########## docs/zh/latest/plugins/limit-req.md: ########## @@ -111,6 +131,169 @@ curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ }' ``` +</TabItem> + +<TabItem value="adc"> + +```yaml title="adc.yaml" +services: + - name: httpbin + routes: + - uris: + - /get + name: limit-req-route + plugins: + limit-req: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` + +将配置同步到网关: + +```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"> + +```yaml title="limit-req-ic.yaml" +apiVersion: v1 +kind: Service +metadata: + namespace: aic + name: httpbin-external-domain +spec: + type: ExternalName + externalName: httpbin.org +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: limit-req-plugin-config +spec: + plugins: + - name: limit-req + config: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: limit-req-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /get + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: limit-req-plugin-config + backendRefs: + - name: httpbin-external-domain + port: 80 +``` + +</TabItem> + +<TabItem value="apisix-crd"> + +```yaml title="limit-req-ic.yaml" +apiVersion: apisix.apache.org/v2 +kind: ApisixUpstream +metadata: + namespace: aic + name: httpbin-external-domain +spec: + ingressClassName: apisix + externalNodes: + - type: Domain + name: httpbin.org +--- +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + namespace: aic + name: limit-req-route +spec: + ingressClassName: apisix + http: + - name: limit-req-route + match: + paths: + - /get + methods: + - GET + upstreams: + - name: httpbin-external-domain + plugins: + - name: limit-req + config: + rate: 1 + burst: 0 + key: remote_addr + key_type: var + rejected_code: 429 + policy: local + nodelay: true +``` + +</TabItem> + +</Tabs> + +应用配置: + +```shell +kubectl apply -f limit-req-ic.yaml +``` + +</TabItem> + +</Tabs> + +❶ `rate`:将 QPS 限制为 1。 + +❷ `key`:设置为 `remote_addr`,以按远程地址和消费者应用速率限制配额。 Review Comment: 此处说明 `key` 会“按远程地址和消费者”应用配额,但本示例仅使用 `remote_addr`,未涉及消费者信息(也未启用认证插件)。建议把表述改为仅按远程地址进行速率限制,避免误导。 ```suggestion ❷ `key`:设置为 `remote_addr`,以按远程地址应用速率限制配额。 ``` -- 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]
