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

使用java.util.regex.Pattern匹配时CPU占用过高问题排查

正则校验导致CPU使用率100%的问题分析与修复

问题背景

在Spring框架结合Hibernate校验的场景中,使用@Pattern进行正则校验时,偶尔出现线程CPU使用率达到100%的情况,线程转储显示线程卡在Pattern类中。

相关代码片段如下:

校验逻辑代码

@PostMapping
public ResponseEntity create(@RequestBody RequestObj request) {
  validationService.validate(request);
  .....
}

请求对象的正则校验注解

public class RequestObj {

  @Pattern(regexp = "^([a-zA-Z])+[-.'\\s]?[-a-zA-Z]*$", message = ValidationConstant.ERR_INVALID_FIRST_NAME)
  @NotNull(message = ValidationConstant.ERR_FIRST_NAME_EMPTY)
  @Size(max = 30, message = ValidationConstant.ERR_INVALID_NAME_SIZE)
  private String firstName;

  @Pattern(regexp = "^[\\sa-zA-Z0-9]+([ a-zA-Z0-9,'.?!\\-_&]+)*$", message = ValidationConstant.ERR_INVALID_COMMENT)
  @Size(max = 200, message = ValidationConstant.ERR_INVALID_COMMENT_SIZE)
  private String comment;

}

问题根源:正则表达式存在回溯陷阱

你的正则表达式确实存在正则回溯陷阱,这是导致CPU飙高的核心原因。当输入不符合规则的字符串时,正则引擎会尝试大量的匹配组合,持续消耗CPU资源。

逐个分析问题正则

  • firstName的正则:^([a-zA-Z])+[-.'\\s]?[-a-zA-Z]*$
    问题点:([a-zA-Z])+和[-a-zA-Z]*的字符范围重叠(均包含字母),当输入类似aaaaa-这类不符合规则的字符串时,正则引擎会反复回溯:先让([a-zA-Z])+匹配所有字母,尝试匹配[-.'\\s]?后发现后续无内容,再逐步减少([a-zA-Z])+的匹配长度,尝试不同组合直到穷尽所有可能,这个过程会持续占用CPU。

  • comment的正则:^[\\sa-zA-Z0-9]+([ a-zA-Z0-9,'.?!\\-_&]+)*$
    问题点:这个正则的回溯问题更严重,[\\sa-zA-Z0-9]+和后续组([ a-zA-Z0-9,'.?!\\-_&]+)*的字符范围几乎完全重叠。当输入较长的不符合规则的字符串时,会触发指数级的回溯,直接导致CPU被占满。

优化后的正则表达式

firstName优化版

^[a-zA-Z]+(?:[-.'\\s][a-zA-Z]+)?$

解释:用非捕获组(?:...)定义可选的后缀部分,只有当存在分隔符[-.'\\s]时,后面才必须跟字母,彻底消除了重叠匹配带来的回溯问题,同时保证规则的正确性(开头为字母,可包含一个分隔符加字母结尾)。

comment优化版

^[\\sa-zA-Z0-9,'.?!\\-_&]+$

解释:将原来嵌套的重复匹配合并为单次的范围匹配,既满足“所有字符都属于指定范围”的规则,又完全避免了回溯陷阱。

额外建议

结合@Size注解的长度限制,校验框架会先校验字符串长度,再执行正则匹配,这可以减少超长字符串进入正则匹配环节,进一步提升校验效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:40:36