mikyll commented on issue #12592: URL: https://github.com/apache/apisix/issues/12592#issuecomment-3257498077
I love how I keep discovering new features (such as `limit-req` that can also be enabled on Consumers) 😄 --- I tried to reproduce the issue on Docker, but unfortunately didn't succeed (it behaves as expected). Below is my [MRE](https://en.wikipedia.org/wiki/Minimal_reproducible_example). ## MRE ### Structure - File `compose.yaml`: ```yaml name: apisix-test-limit-req services: etcd: image: bitnami/etcd:latest environment: ALLOW_NONE_AUTHENTICATION: yes healthcheck: test: "etcdctl endpoint health" interval: 5s timeout: 30s retries: 5 networks: apisix: apisix: image: apache/apisix:3.12.0-debian stdin_open: true tty: true depends_on: etcd: condition: service_healthy redis: condition: service_healthy ports: - "9080:9080/tcp" - "9180:9180/tcp" - "9443:9443/tcp" volumes: - ./conf/config.yaml:/usr/local/apisix/conf/config.yaml networks: apisix: redis: image: bitnami/redis:8.2.1-debian-12-r0 healthcheck: test: "redis-cli ping | grep PONG" interval: 5s timeout: 30s retries: 5 environment: ALLOW_EMPTY_PASSWORD: yes networks: apisix: httpbin: image: kennethreitz/httpbin:latest ports: - "3000:80/tcp" networks: apisix: networks: apisix: driver: bridge ``` - File `conf/config.yaml`: ```yaml apisix: router: http: radixtree_uri_with_parameter node_listen: 9080 deployment: admin: admin_key_required: true admin_key: - name: admin key: 1a8fe9bd-73ab-493c-ac82-44db40eab641 role: admin - name: guest key: guest role: viewer allow_admin: - 127.0.0.0/24 - 0.0.0.0/0 admin_listen: ip: 0.0.0.0 port: 9180 etcd: host: - http://etcd:2379 prefix: "/apisix" timeout: 30 plugins: - jwt-auth - proxy-rewrite - limit-req ``` Then started the containers: ```bash docker compose up ``` Or with Podman: ```bash podman-compose up ``` ### Resources Creation I created the following resources: - 3 APISIX routes: - `/test` – base request to httpbin `/get` endpoint - `/test-jwt-auth-local` – route with anonymous `jwt-auth` to test **local** policy - `/test-jwt-auth-redis` – route with anonymous `jwt-auth` to test **redis** policy - 2 APISIX consumers: - `anonymous_local` – anonymous consumer with `jwt-auth` and `limit-req` (**local** policy) - `anonymous_redis` – anonymous consumer with `jwt-auth` and `limit-req` (**redis** policy) ```bash ADMIN_API_KEY="1a8fe9bd-73ab-493c-ac82-44db40eab641" # Test route /test curl -X PUT "localhost:9180/apisix/admin/routes/test" -H "X-Api-Key: ${ADMIN_API_KEY}" -d ' { "uri": "/test", "upstream": { "type": "roundrobin", "nodes": { "httpbin:80": 1 } }, "plugins": { "proxy-rewrite": { "uri": "/get" } } } ' # Test route /test-jwt-auth-local curl -X PUT "localhost:9180/apisix/admin/routes/test-jwt-auth-local" -H "X-Api-Key: ${ADMIN_API_KEY}" -d ' { "uri": "/test-jwt-auth-local", "upstream": { "type": "roundrobin", "nodes": { "httpbin:80": 1 } }, "plugins": { "proxy-rewrite": { "uri": "/get" }, "jwt-auth": { "anonymous_consumer": "anonymous_local" } } } ' # Test route /test-jwt-auth-redis curl -X PUT "localhost:9180/apisix/admin/routes/test-jwt-auth-redis" -H "X-Api-Key: ${ADMIN_API_KEY}" -d ' { "uri": "/test-jwt-auth-redis", "upstream": { "type": "roundrobin", "nodes": { "httpbin:80": 1 } }, "plugins": { "proxy-rewrite": { "uri": "/get" }, "jwt-auth": { "anonymous_consumer": "anonymous_redis" } } } ' # Anonymous consumer (limit-req: local) curl -X PUT "localhost:9180/apisix/admin/consumers/anonymous_local" -H "X-Api-Key: ${ADMIN_API_KEY}" -d ' { "username": "anonymous_local", "desc": "Test consumer for limit-req, local policy", "plugins": { "limit-req": { "_meta": { "disable": false }, "allow_degradation": false, "burst": 0, "key": "remote_addr", "key_type": "var", "policy": "local", "rate": 1, "rejected_code": 429, "rejected_msg": "Too many requests in time window (local)" }, "jwt-auth": { "key": "key_local" } } } ' # Anonymous consumer (limit-req: redis) curl -X PUT "localhost:9180/apisix/admin/consumers/anonymous_redis" -H "X-Api-Key: ${ADMIN_API_KEY}" -d ' { "username": "anonymous_redis", "desc": "Test consumer for limit-req, redis policy", "plugins": { "limit-req": { "_meta": { "disable": false }, "allow_degradation": false, "burst": 0, "key": "remote_addr", "key_type": "var", "policy": "redis", "rate": 1, "redis_database": 0, "redis_host": "redis", "redis_timeout": 1000, "rejected_code": 429, "rejected_msg": "Too many requests in time window (redis)" } } } ' ``` ### Test #### Case 1 - Local Policy ```bash for i in {1..5}; do curl -s localhost:9080/test-jwt-auth-local | jq -c; done ``` Result: ```bash {"args":{},"headers":{"Accept":"*/*","Host":"localhost:9080","User-Agent":"curl/8.5.0","X-Consumer-Username":"anonymous_local","X-Forwarded-Host":"localhost"},"origin":"10.89.18.21","url":"http://localhost/get"} {"error_msg":"Too many requests in time window (local)"} {"error_msg":"Too many requests in time window (local)"} {"error_msg":"Too many requests in time window (local)"} {"error_msg":"Too many requests in time window (local)"} ``` APISIX Logs: ```lang-none [apisix] | 2025/09/05 08:18:51 [warn] 48#48: *1422 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-local HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:18:51 [warn] 46#46: *1423 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-local HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:18:51 [warn] 75#75: *1424 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-local HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:18:51 [warn] 48#48: *1425 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-local HTTP/1.1", host: "localhost:9080" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:18:51 +0000] localhost:9080 "GET /test-jwt-auth-local HTTP/1.1" 200 269 0.007 "-" "curl/8.5.0" 10.89.18.20:80 200 0.005 "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:18:51 +0000] localhost:9080 "GET /test-jwt-auth-local HTTP/1.1" 429 68 0.000 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:18:51 +0000] localhost:9080 "GET /test-jwt-auth-local HTTP/1.1" 429 68 0.000 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:18:51 +0000] localhost:9080 "GET /test-jwt-auth-local HTTP/1.1" 429 68 0.000 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:18:51 +0000] localhost:9080 "GET /test-jwt-auth-local HTTP/1.1" 429 68 0.000 "-" "curl/8.5.0" - - - "http://localhost:9080/get" ``` #### Case 2 - Redis Policy ```bash for i in {1..5}; do curl -s localhost:9080/test-jwt-auth-redis | jq -c; done ``` Result: ```bash {"args":{},"headers":{"Accept":"*/*","Host":"localhost:9080","User-Agent":"curl/8.5.0","X-Consumer-Username":"anonymous_redis","X-Forwarded-Host":"localhost"},"origin":"10.89.18.21","url":"http://localhost/get"} {"error_msg":"Too many requests in time window (redis)"} {"error_msg":"Too many requests in time window (redis)"} {"error_msg":"Too many requests in time window (redis)"} {"error_msg":"Too many requests in time window (redis)"} ``` APISIX Logs: ```lang-none [apisix] | 2025/09/05 08:19:31 [warn] 86#86: *3766 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-redis HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:19:31 [warn] 55#55: *3770 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-redis HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:19:31 [warn] 55#55: *3774 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-redis HTTP/1.1", host: "localhost:9080" [apisix] | 2025/09/05 08:19:31 [warn] 54#54: *3776 [lua] plugin.lua:1210: run_plugin(): limit-req exits with http status code 429, client: 10.89.18.21, server: _, request: "GET /test-jwt-auth-redis HTTP/1.1", host: "localhost:9080" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:19:31 +0000] localhost:9080 "GET /test-jwt-auth-redis HTTP/1.1" 200 269 0.007 "-" "curl/8.5.0" 10.89.18.20:80 200 0.003 "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:19:31 +0000] localhost:9080 "GET /test-jwt-auth-redis HTTP/1.1" 429 68 0.002 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:19:31 +0000] localhost:9080 "GET /test-jwt-auth-redis HTTP/1.1" 429 68 0.002 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:19:31 +0000] localhost:9080 "GET /test-jwt-auth-redis HTTP/1.1" 429 68 0.001 "-" "curl/8.5.0" - - - "http://localhost:9080/get" [apisix] | 10.89.18.21 - - [05/Sep/2025:08:19:31 +0000] localhost:9080 "GET /test-jwt-auth-redis HTTP/1.1" 429 68 0.002 "-" "curl/8.5.0" - - - "http://localhost:9080/get" ``` --- As we can notice, in both cases, only 1 request (of the 5 total) passes in a time frame of 1 second 👀 -- 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]
