tomcat返回429肿么办

403 阅读1分钟

问题分析

tomcat在某些情况下会返回:

429 Too Many Requests

意思就是tomcat接收的请求太多

源码解析

org.apache.catalina.filters.RateLimitFilter

tomcat默认会有一个RateLimitFilter 实现的doFilter核心逻辑:

  1. 获取远程ip
  2. 计算当前ip在周期类的请求数
  3. 判断当前周期内的请求数是否超过限制
  4. 超过就返回异常码429
  5. 否则就走下一个Filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    String ipAddr = request.getRemoteAddr();
    int reqCount = bucketCounter.increment(ipAddr);

    request.setAttribute(RATE_LIMIT_ATTRIBUTE_COUNT, Integer.valueOf(reqCount));

    if (enforce && (reqCount > actualRequests)) {

        ((HttpServletResponse) response).sendError(statusCode, statusMessage);
        log.warn(sm.getString("rateLimitFilter.maxRequestsExceeded", filterName, Integer.valueOf(reqCount), ipAddr,
                Integer.valueOf(getActualRequests()), Integer.valueOf(getActualDurationInSeconds())));

        return;
    }

    chain.doFilter(request, response);
}

actualRequests默认情况下是300 统计窗口周期为10秒

调优

<filter>
  <filter-name>rateLimiterFilter</filter-name>
  <filter-class>
    org.apache.catalina.filters.RateLimitFilter
  </filter-class>
  <init-param>
    <param-name>bucketRequests</param-name>
    <param-value>500</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>rateLimiterFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

调整bucketRequests来提高每个ip在10秒内可以处理的请求数,但是需要根据具体业务、情况来,提高这个值会导致cpu、内存提高以及可能导致gc的一些问题。