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]

Reply via email to