{"record":{"id":"7db6f4bcf0a97859","repo":"crossoverJie/JCSprout","slug":"request-has-bean-limit","errorCode":null,"errorMessage":"request has bean limit","messagePattern":"request has bean limit","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"MD/distributed/Distributed-Limit.md","lineNumber":458,"sourceCode":"    private static Logger logger = LoggerFactory.getLogger(CommonAspect.class);\n\n    @Autowired\n    private RedisLimit redisLimit ;\n\n    @Pointcut(\"@annotation(com.crossoverjie.distributed.annotation.CommonLimit)\")\n    private void check(){}\n\n    @Before(\"check()\")\n    public void before(JoinPoint joinPoint) throws Exception {\n\n        if (redisLimit == null) {\n            throw new NullPointerException(\"redisLimit is null\");\n        }\n\n        boolean limit = redisLimit.limit();\n        if (!limit) {\n            logger.warn(\"request has bean limit\");\n            throw new RuntimeException(\"request has bean limit\") ;\n        }\n\n    }\n}\n```\n\n很简单，也是在拦截过程中调用限流。\n\n当然使用时也得扫描到该包:\n\n```java\n@ComponentScan(value = \"com.crossoverjie.distributed.intercept\")\n```\n\n### 总结\n\n**限流**在一个高并发大流量的系统中是保护应用的一个利器，成熟的方案也很多，希望对刚了解这一块的朋友提供一些思路。\n","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/crossoverJie/JCSprout/blob/fc4c6e5f6d1772c2aec4c0f94cb3c8e7eb04018f/MD/distributed/Distributed-Limit.md#L440-L476","documentation":"Thrown by the CommonAspect @Before advice when redisLimit.limit() returns false, meaning the rate-limit check denied the request. This is the intended rate-limiting behaviour (the typo 'bean' should read 'been'): the caller has exceeded the configured request rate within the time window, so the aspect aborts the method invocation with a RuntimeException. It surfaces as a 500 to the HTTP caller unless caught by a controller advice.","triggerScenarios":"A client calls a @CommonLimit-annotated method more times than the configured Redis-based limit allows within the sliding/fixed window. Under load testing (e.g. JMeter) a large fraction of requests hit this path once the rate budget is exhausted.","commonSituations":"Rate limit threshold set too low for legitimate traffic. Burst traffic from a single client or a shared NAT egress IP. The limit key (typically IP-based) collides because all requests appear to come from the same source behind a proxy without X-Forwarded-For handling. Load testing without accounting for rate limits.","solutions":["Tune the rate-limit parameters (requests per window) in the @CommonLimit annotation or Redis config to match your traffic profile.","Add a @ControllerAdvice / @ExceptionHandler that catches this RuntimeException and returns HTTP 429 (Too Many Requests) instead of a 500.","Ensure the limit key correctly distinguishes clients (forward real IP from proxy headers) so one client does not exhaust the budget for all.","If the limit is expected, handle it client-side with backoff and retry."],"exampleFix":"// before — caller gets a raw 500\nthrow new RuntimeException(\"request has bean limit\");\n\n// after — return a proper 429\n@ControllerAdvice\npublic class RateLimitHandler {\n    @ExceptionHandler(RuntimeException.class)\n    public ResponseEntity<String> onRateLimit(RuntimeException e) {\n        if (e.getMessage() != null && e.getMessage().contains(\"limit\")) {\n            return ResponseEntity.status(429).body(\"Rate limit exceeded\");\n        }\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// No pre-call validation can prevent this — it is the rate limit working as designed.\n// Instead, track your request rate client-side and back off if approaching the limit.","typeGuard":null,"tryCatchPattern":"// Server-side: convert the raw RuntimeException into a proper 429.\n@ControllerAdvice\npublic class RateLimitExceptionHandler {\n    @ExceptionHandler\n    public ResponseEntity<String> handle(RuntimeException e) {\n        if (e.getMessage() != null && e.getMessage().contains(\"limit\")) {\n            return ResponseEntity.status(429)\n                .header(\"Retry-After\", \"1\")\n                .body(\"Rate limit exceeded, please retry later.\");\n        }\n        throw e;\n    }\n}","preventionTips":["Tune the @CommonLimit rate parameters to match your expected traffic.","Add a @ControllerAdvice to convert the RuntimeException into HTTP 429 so clients get a clear signal.","On the client side, implement exponential backoff when receiving 429 responses.","Ensure the rate-limit key distinguishes real clients if behind a shared proxy."],"tags":["rate-limiting","aop","spring","traffic-control"],"backgroundTag":null,"analyzedSha":"fc4c6e5f6d1772c2aec4c0f94cb3c8e7eb04018f","analyzedAt":"2026-08-14T05:43:20.992Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}