You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot3中@Size验证大List引发CPU占满,该如何解决?

问题分析与解决方案

这是不是@Size的Bug?

不是Bug。原因在于:@Size注解验证List集合大小的前提是请求体已经被完整反序列化为List对象,当传入70万条数据时,Spring需要先把整个JSON请求体转换成包含70万个TestDTO实例的List,这个反序列化过程本身就会消耗大量CPU资源(解析超大规模JSON、创建大量对象),导致CPU占用率拉满。@Size只是在反序列化完成后读取集合size做判断,它本身的逻辑非常简单,并没有性能问题。

其他解决方案

除了限制请求体大小,你可以尝试以下几种方案:

  • 提前拦截超大规模请求
    通过Spring Boot配置在请求到达控制器前直接拦截过大的请求体,避免进入反序列化流程。在application.yml或application.properties中配置:

    server:
      tomcat:
        max-http-post-size: 5MB # 根据单条TestDTO的大小估算,比如每条100字节,3条仅300字节,设置远低于70万条对应的大小
        connection-timeout: 2000 # 可选,缩短超时时间快速拒绝大请求
    
  • 自定义前置验证拦截器
    编写一个Filter或Interceptor,在请求进入控制器前先读取请求体的字节长度,结合单条TestDTO的预估大小计算大致条数,若超过限制(比如3条)直接返回错误响应,无需反序列化整个集合。注意要使用ContentCachingRequestWrapper包装请求,避免请求体被读取后无法再次使用:

    @Component
    public class RequestSizeFilter extends OncePerRequestFilter {
        private static final int MAX_ALLOWED_BYTES = 300; // 假设3条TestDTO约300字节
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
            byte[] requestBody = wrappedRequest.getContentAsByteArray();
            if (requestBody.length > MAX_ALLOWED_BYTES) {
                response.setStatus(HttpStatus.BAD_REQUEST.value());
                response.getWriter().write("请求数据条数超过限制");
                return;
            }
            filterChain.doFilter(wrappedRequest, response);
        }
    }
    
  • 调整接口接收方式
    如果业务允许,避免一次性接收大量集合数据:

    • 将接口改为分批接收数据,比如每次最多传3条;
    • 改用@RequestParam接收单个参数,而非整个List集合。
  • 优化验证注解的使用
    确保控制器类上的@Validated和方法参数的@Valid注解没有重复触发不必要的验证。你当前代码中@RequestBody前有两个@Valid,可以去掉一个,避免重复验证开销。

内容的提问来源于stack exchange,提问作者user24450259

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:43:40