目录
一.背景
二.正则表达式回溯
三.解决方案
一.背景
前面讲解了如果排查应用程序代码引起的cpu飙高。
对于死循环、某一行代码执行次数多引起cpu高,这一类都可以定位。
这一节通过一个容易发生但是也容易被忽略的案例正则表达式回溯引起的飙高来讲解。
二.正则表达式回溯
可以看出cpu已经占满,为什么会占满?
我们一步一步来看,是怎么处理的。
让我们一步一步来看:
匹配开始(a*)捕获尽可能多的字符a。
(a*)一直捕获,直到遇到字符b。这时(a*)已经捕获了aaaaa...。
正则表达式继续执行(a*)之后的a匹配。但此时由于字符串剩一个 s字符。导致无法完成匹配。
(a*)从已捕获的字符串中“吐”出一个字符a。尝试去匹配。
重复执行3.4直至结束。
从第3,4步可以看到,暂时的无法匹配并不会立即导致整体匹配失败。而是会从捕获组中“吐出”字符以尝试。这个“吐出”的过程就叫回溯。
随着字符串长度变长,回溯的次数也是指数级的上升,最终导致CPU被占满。
三.解决方案
1.高并发下尽可能不使用正则,正则本身就耗CPU。
2.禁止回溯
尽可能的少发生回溯。
比如(a+)*s,改为:aa*s
网友评论