当前位置: 首页 > news >正文

问题记录:一个简单的字符串正则匹配算法引发的 CPU 告警

一、背景

今天上班的时候发生了一件事,客户的服务器 CPU 的使用率持续的出现告警,登录服务器发现达到了 3000% 的 CPU 使用,使用 Arthas 查看线程堆栈发现全部都是 URL 正则匹配导致的问题。感慨一个简单正则匹配算法,因为使用了复杂度比较高的算法,在海量数据的环境下居然会出现这么大的影响。
这是一个非常典型的性能问题 ⚠️——正则表达式匹配 URL 导致 CPU 使用率过高
我们可以从根本原因分析 → 优化方向 → 替代方案 三个层次来理解和解决。

二、为什么正则会导致高 CPU 占用?

  1. 正则表达式本身是“回溯型算法”

    • Java(以及大多数语言)默认的正则引擎是 NFA(非确定有限自动机)
    • 在复杂的表达式(特别是带有重复量词 .*, .+, (.*)+, (?:a|aa)* 等)时,会出现指数级回溯
    • 对于长字符串(例如 URL、HTML 文本等),某些匹配会让正则“疯狂回溯”,CPU 飙升。

举例:

String pattern = ".*(http|https)://.*";
String url = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
// 极易造成大量无意义的匹配尝试
  1. URL 结构复杂

    • URL 含有多种字符:/ ? & = # % + 等。
    • 如果正则没有精确限定,会触发“贪婪匹配 + 回溯”。
    • 特别是在循环或批量日志扫描中使用时,CPU 会飙升。
  2. 重复编译 Pattern

    • 每次 Pattern.compile(regex) 都会重新构建 DFA 树。
    • 在高频调用(如每秒数万次匹配)下,这个开销非常大。

三、优化方向

1. 预编译 Pattern

错误示例:

boolean isMatch = Pattern.matches("https?://[^\\s]+", url);

每次都重新编译正则!

正确做法:

private static final Pattern URL_PATTERN = Pattern.compile("https?://[^\\s]+");boolean isMatch = URL_PATTERN.matcher(url).find();

在高并发系统中,这一项 alone 就能减少 90% 以上 CPU 消耗。

2. 优化正则表达式结构

URL 匹配常见优化:

^https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+$

要点:

  • 限制匹配范围:^$
  • 避免贪婪的 .*
  • 用字符类 [A-Za-z0-9...] 替代 .*

3. 避免在循环中重复创建 Matcher

错误示例:

for (String url : urls) {Matcher matcher = Pattern.compile(REGEX).matcher(url);if (matcher.find()) ...
}

正确示例:

Pattern p = Pattern.compile(REGEX);
for (String url : urls) {Matcher matcher = p.matcher(url);if (matcher.find()) ...
}

4. 分层匹配(先粗后细)

如果你只是想判断字符串中是否包含 URL:

// 先粗筛
if (url.contains("http")) {// 再用正则精确匹配...
}

这种“分层判断”能大幅减少进入正则的次数。

5. 使用高性能替代方案

如果你频繁解析或匹配 URL:

  • 使用标准库解析器:

    try {new java.net.URL(url);
    } catch (MalformedURLException e) {// not a valid URL
    }
    

    内部是基于状态机实现的,性能远优于正则。

  • 使用 RE2/J(Google 实现的无回溯正则引擎)

    <dependency><groupId>com.google.re2j</groupId><artifactId>re2j</artifactId><version>1.7</version>
    </dependency>
    
    import com.google.re2j.Pattern;
    Pattern p = Pattern.compile("https?://[^\\s]+");
    

    RE2 不会出现“指数回溯”,CPU 占用稳定。

四、如何定位正则导致的高 CPU

  1. 使用 Java Flight Recorder / VisualVM / async-profiler

    • 观察 CPU 栈中是否存在 java.util.regex.Pattern$Branch.matchBacktrackMatcher.
    • 如果出现这些方法在栈顶 → 说明是正则回溯问题。
  2. 通过日志确认输入数据特征

    • 找出那些引起 CPU 飙升的长字符串。
    • 检查正则是否会在这些输入上产生灾难性回溯。

五、推荐方案总结表

场景推荐方案原因
简单 URL 判断预编译轻量正则快速、低成本
解析 URL 结构java.net.URL无回溯,稳健
大规模匹配RE2/J 引擎防止灾难性回溯
批量数据流粗筛 + 精匹配控制匹配频率
动态匹配规则缓存 Pattern避免重复编译
http://www.dtcms.com/a/462632.html

相关文章:

  • 公共数据资源的“整体授权”是什么涵义?
  • 如何增加网站关键词密度网站建设与维护网课
  • 建立门户网站的程序漳州企业网站建设制作
  • 汕头房产网站建设公司网站界面设计
  • [7-01-02].第05节:环境搭建 - 基础环境
  • BLIP模型
  • 网站建设添加资料搜索引擎优化seo什么意思
  • Playwright与Python:从入门到精通的完整指南
  • maven本地仓库有相应的依赖,依旧会从远程仓库拉取问题的原因及解决
  • 如何修改wordpress站景区旅游网站平台建设方案
  • 网站建设拾金手指下拉十九济南天桥区做网站的
  • 甘肃水利工程建设管理网站东省住房和城乡建设厅网站
  • 10.9 换根dp
  • 上海做网站设计温州专业微网站制作多少钱
  • Trino:一个开源分布式大数据SQL查询引擎
  • 网站建设岗位职责做网站能致富吗
  • 网站优化方案设计wordpress删除用户头像
  • C# 弃元模式:从语法糖到性能利器的深度解析
  • 外国优秀网站欣赏广东茂名网站建设
  • 网站备案的用户名是什么广州比较好的网站建设
  • INT301 Bio-computation 生物计算(神经网络)Pt.1 导论与Hebb学习规则
  • 百度站长平台男女做暖暖的网站大全
  • 乌克兰集团网站建设wordpress 产品目录
  • C#基础16-C#6-C#9新特性
  • 两个RNA-蛋白以及蛋白间相互作用数据库
  • 《低速园区场景下决策模块的成本函数设计与编程实践》
  • 网站推广方法是什么企业网站建设cms系统
  • SpringBoot 集成 LangChain4j 本地调用 Ollama
  • 大前端最新网站设计一个企业官网的栏目
  • Vue 菜单权限管理的计与实现