【求助】关于近期网站程序Regex引发奇怪的404现象

首先简单描述一下网站情况,图画并不严谨,差不多就那个意思

2011053111253290.jpg
1、网站通过继承IHttpModule将用户的所有原始Url请求通过有个Rule配置文件进行UrlRewrite重写
2、Rule的匹配规则判断也是通过正则表达式实现的
3、然后开始业务逻辑处理,最后返回给IIS,IIS再返回给用户
PS:代码中大量使用到Regex函数,静态方法和创建实例对象的情况都有,至少有100处+
好了,现在看来一切安好,并且之前网站运行都很正常,至少在09年到11年4月份之间吧,但是4月份之后,网站突然出现了404报警,并且所有页面请求全部404,通过查看线上服务器的Event Log找到了一些线索,如下:
异常信息: 
    异常类型: NullReferenceException 
    异常消息: 未将对象引用设置到对象的实例。 
请求信息: 
    请求 URL: http://info5.58.com/Default.aspx?LocalName=bj&CateName=mpvkuche
    请求路径: /Default.aspx 
    用户主机地址: 127.0.0.1 
堆栈跟踪:
    在 System.Collections.Generic.LinkedListNode`1.get_Next()
    在 System.Text.RegularExpressions.Regex.LookupCachedAndUpdate(String key)
    在 System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options, Boolean useCache)
    在 Components.XmlHelper.GetUrlReWriteXml(String from, String par, String url)
    位置 \Components\XmlHelper.cs:行号 98
    在 UrlReWrite.ReWriteUrl(Object source, EventArgs e)
    位置 \Components\IHttpModule\UrlReWriteModule.cs:行号 120

有了上面这些线索后我们就可以开始分析了,首先找到引发出错的代码,也就是XmlHelper类的GetUrlReWriteXml这个方法,这个方法用来做啥的? 其实就是 将所有的用户的原始请求Url通过调用这个方法进行url重写并返回重写后的url,查看该方法的代码,发现了有用到正则的代码,如下
Regex reg = new Regex(@"[a-zA-Z]+\=&", RegexOptions.IgnoreCase | RegexOptions.Singleline);
string currentUrl = reg.Replace(url, SendTo);
到了这里继续追踪就需要使用Reflector工具将.net的System.Text.RegularExpressions.Regex源码反编译了
OK,我们继续往上追踪看到的是 System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options, Boolean useCache)

“.ctor”这是个什么东西呢?熟悉IL的都知道他其实是个对象初始化命令,相当于构造函数。

但为什么代码中写的其实是Regex reg = new Regex(@"[a-zA-Z]+\=&", RegexOptions.IgnoreCase | RegexOptions.Singleline);,而IL中转换以后调用的是 Regex..ctor(String pattern, RegexOptions options, Boolean useCache)这个构造函数呢?最后面多了一个布尔的参数,还是看.net的源码吧
2011053111260269.jpg
OK,现在明白怎么回事了,不理丫的咱们继续追踪!
2011053111263024.jpg
在上面的代码中找到了调用 System.Text.RegularExpressions.Regex.LookupCachedAndUpdate(String key)的地方,继续追踪该方法
2011053111265798.jpg
经过这么多步骤终于找到了出现真正问题的地方,其实是在  System.Collections.Generic.LinkedListNode`1.get_Next()的时候出现了 未将对象引用设置到对象的实例的异常。
我们来看一下 LinkedListNode<CachedCodeEntry>这又是个什么?
这里需要了解一下Regex函数静态方法的一些相关内部机制,关键词 LinkedList<T>,CachedCodeEntry,cacheSize
1、首先.net为了提高Regex函数静态方法的性能,他自己内部维护了一个名为 livecode的变量和 cacheSize 的变量,如图
2011053111272385.jpg
livecode对象实际上是Regex 类维护用于静态方法调用的已编译的正则表达式的内部缓存, 默认情况下,缓存可容纳 15 个已编译的正则表达式,并且可以通过 cacheSize 改变缓存的容量。
这里的概念可以参考微软的说明
其实 livecode对象对于Regex 函数的静态方法和实例方法都会使用他,但是只有在使用静态方法的时候才会将其内部缓存起来,实例方法是不会进行缓存操作的。

现在基本上都明白是怎么回事了,但最郁闷的就是不知道为什么网站运行的时候node.Next的时候会出现null的情况,而且没有任何规律,访问高峰的时候出现过,夜里2、3点中也出现过,基本上一周时间可能会出现1-2次这种情况, 网站程序代码里面确实有大量用到Regex 静态或实例的方法,只要一出现那种情况,就会导致所有正则的地方全部会报异常,从而出现404!!!

目前想到的解决办法:
1、将所有静态方法改为实例方法,这样他就不会向缓存中插入已编译的正则表达式,避免从缓存中取
2、将Regex 的 cacheSize 设为0,其实就是变相的关闭缓存,性能上稍微的有所损失但影响不大

兄弟们谁遇到过类似问题给点思路建议吧。。。

转载于:https://www.cnblogs.com/An-Yang/archive/2011/05/31/2064127.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你使用这段代码时,你需要先定义正则表达式的模式,并将其存储在`regex_data`变量中。这个变量可以存储一个字符串或者一个正则表达式对象。例如,如果你想匹配一个字符串中的所有数字,你可以这样定义`regex_data`变量: ``` import re regex_data = r'\d+' text = 'Today is 2021-06-15, and it is a sunny day.' matches = re.findall(regex_data, text) print(matches) ``` 这段代码中,`regex_data`存储的是一个正则表达式字符串`r'\d+'`,它表示匹配一个或多个数字。然后,我们使用Python的正则表达式模块`re`对字符串`text`进行匹配,将匹配结果存储在`matches`变量中。最后,我们打印出匹配结果,输出为`['2021', '06', '15']`。 另一个实例,如果你想匹配一个HTML标签中的所有属性名和属性值,你可以这样定义`regex_data`变量: ``` import re regex_data = r'\s+(\w+)\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([^\s>]+))' text = '<div class="container" id=\'main\' custom-attr="123">Hello, world!</div>' matches = re.findall(regex_data, text) print(matches) ``` 这段代码中,`regex_data`存储的是一个正则表达式字符串,它可以匹配HTML标签中的所有属性名和属性值。然后,我们使用Python的正则表达式模块`re`对字符串`text`进行匹配,将匹配结果存储在`matches`变量中。最后,我们打印出匹配结果,输出为`[('class', 'container', '', ''), ('id', '', 'main', ''), ('custom-attr', '', '', '123')]`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值