[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-rest-api-chto-takoe-rate-limiting-i-kak-ego-realizovat":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},1225,"chto-takoe-rate-limiting-i-kak-ego-realizovat",34,"rest-api","REST API","🌐","Что такое Rate Limiting и как его реализовать?","Rate Limiting (ограничение частоты запросов) — механизм защиты API от злоупотреблений и перегрузки путём ограничения количества запросов от клиента за определённый период времени.\n\n### Основные алгоритмы\n\n| Алгоритм | Описание |\n|----------|----------|\n| Fixed Window | Подсчёт запросов в фиксированных временных интервалах (100 запросов в минуту) |\n| Sliding Window | Более точный, учитывает запросы за последние N секунд |\n| Token Bucket | Жетоны добавляются с постоянной скоростью. Каждый запрос забирает жетон. Нет жетонов — отказ |\n| Leaky Bucket | Запросы обрабатываются с постоянной скоростью, избыточные ставятся в очередь |\n\n### HTTP-заголовки для Rate Limiting\n\n```\nHTTP\u002F1.1 200 OK\nX-RateLimit-Limit: 100           — максимум запросов\nX-RateLimit-Remaining: 45        — осталось запросов\nX-RateLimit-Reset: 1700000060    — время сброса (Unix timestamp)\n\nHTTP\u002F1.1 429 Too Many Requests\nRetry-After: 30                  — через сколько секунд повторить\n```\n\n\u003Cdetails>\u003Csummary>Реализация в Spring с помощью Bucket4j\u003C\u002Fsummary>\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.bucket4j\u003C\u002FgroupId>\n    \u003CartifactId>bucket4j-core\u003C\u002FartifactId>\n    \u003Cversion>8.7.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n```java\n@Component\npublic class RateLimitFilter extends OncePerRequestFilter {\n\n    private final Map\u003CString, Bucket> buckets = new ConcurrentHashMap\u003C>();\n\n    @Override\n    protected void doFilterInternal(HttpServletRequest request,\n                                     HttpServletResponse response,\n                                     FilterChain filterChain)\n            throws ServletException, IOException {\n\n        String clientId = getClientId(request);\n        Bucket bucket = buckets.computeIfAbsent(clientId, this::createBucket);\n\n        ConsumptionProbe probe = bucket.tryConsumeAndReturnRemaining(1);\n        response.setHeader(\"X-RateLimit-Limit\", \"100\");\n        response.setHeader(\"X-RateLimit-Remaining\",\n                           String.valueOf(probe.getRemainingTokens()));\n\n        if (probe.isConsumed()) {\n            filterChain.doFilter(request, response);\n        } else {\n            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());\n            response.setHeader(\"Retry-After\",\n                String.valueOf(probe.getNanosToWaitForRefill() \u002F 1_000_000_000));\n            response.getWriter().write(\"{\\\"error\\\": \\\"Превышен лимит запросов\\\"}\");\n        }\n    }\n\n    private Bucket createBucket(String clientId) {\n        return Bucket.builder()\n            .addLimit(Bandwidth.classic(100, Refill.greedy(100, Duration.ofMinutes(1))))\n            .build();\n    }\n\n    private String getClientId(HttpServletRequest request) {\n        String apiKey = request.getHeader(\"X-API-Key\");\n        return apiKey != null ? apiKey : request.getRemoteAddr();\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\u003Csummary>Реализация через Spring Cloud Gateway\u003C\u002Fsummary>\n\n```yaml\nspring:\n  cloud:\n    gateway:\n      routes:\n        - id: user-service\n          uri: lb:\u002F\u002Fuser-service\n          predicates:\n            - Path=\u002Fapi\u002Fusers\u002F**\n          filters:\n            - name: RequestRateLimiter\n              args:\n                redis-rate-limiter.replenishRate: 10\n                redis-rate-limiter.burstCapacity: 20\n                key-resolver: \"#{@userKeyResolver}\"\n```\n\n```java\n@Bean\npublic KeyResolver userKeyResolver() {\n    return exchange -> Mono.just(\n        exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());\n}\n```\n\n\u003C\u002Fdetails>\n\n> **На собеседовании:** нужно знать алгоритмы (Token Bucket самый популярный), HTTP-заголовки (429, Retry-After, X-RateLimit-*) и хотя бы один способ реализации. Частая ошибка — не упомянуть заголовок Retry-After для клиента.","","middle",[15],"rest",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":23,"featuredSnippetReady":24},"Что такое Rate Limiting и как его реализовать? — Gymterview","Rate Limiting (ограничение частоты запросов) — механизм защиты API от злоупотреблений и перегрузки путём ограничения количества запросов от клиента за определён","Rate Limiting (ограничение частоты запросов) — механизм защиты API от злоупотреблений и перегрузки путём ограничения кол",[15,13],"Rate Limiting (ограничение частоты запросов) — механизм защиты API от злоупотреблений и перегрузки путём ограничения количества запросов от клиента за определённый период времени.",true]