IIS8 RewriteModule / URLRewrite Extremely Slow



我在Windows Server 2012上运行一个带有IIS8的网站。我正在尝试确定导致 IIS 高 CPU 使用率的原因(IIS 通常 CPU 使用率为 50% 或更多(。服务器全天每秒接收大约 40 个请求,但每秒可能只有 1-2 个 URL 需要处理。

我启用了请求跟踪,发现某些 RewriteModule 请求需要 100 秒 (!( 才能完成。我无法确定在具有足够硬件的计算机上如何做到这一点。完全相同的URL结构在不到一秒钟的时间内通过Apache上的mod_rewrite进行处理。

示例 URL 如下所示:

http://<domain-name>/Product/<Parent-Category>/<Child-Category1>/<Child-Category2>/<Child-Category3>/<Product-Name>

随附的重写规则为:

<rule name="Rule" stopProcessing="true">
<match url="^Product/([^/?]+)/?([^/?]+)?/?([^/?]+)?/?([^/?]+)?/?([^/?]+)?/?([^/?]+)?/?[?]?(.+)?$"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="/Product/index.php?a={R:1}&amp;b={R:2}&amp;c={R:3}&amp;d={R:4}&amp;e={R:5}&amp;f={R:6}&amp;{R:7}" appendQueryString="true"/>
</rule>

在我定义匹配网址的过程中,是否有某些因素导致了较长的处理时间?如果某些匹配的 url 使用许多父/子类别(最多 5 个,通常为 3-4 个(,则它们包含大量字符。

问题肯定出在你的正则表达式中。最好的方法是尝试将其拆分为不同的更具体的模式。

如果不是这种情况,此规则应保持相同的功能并更快地工作:

<rule name="Rule" stopProcessing="true">
<match url="^Product/([^/]+)/?([^/]+)?/?([^/]+)?/?([^/]+)?/?([^/]+)?/?([^/]+)?"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="/Product/index.php?a={R:1}&amp;b={R:2}&amp;c={R:3}&amp;d={R:4}&amp;e={R:5}&amp;f={R:6}" appendQueryString="true"/>
</rule>

我删除了正则表达式中不必要的?检查,因为<match url内部的模式正在检查没有查询字符串的 URL,因此,在您的正则表达式中进行?检查是多余的。

我在PC上检查了一下,它的工作速度肯定更快,但是您需要仔细检查它是否保持相同的功能

我做了广泛的测试并将规则更改为以下内容。这导致 CPU 下降到 1%,之前的 100 秒完成时间下降到大约 50 毫秒。

我仍然不明白这怎么可能 - 这是一台具有 4GB RAM 的 4 CPU/8 核机器,IIS8 花了 100 秒来拆开一个 70 个字符的字符串并将其与以前的正则表达式进行比较。除非前面的例子以某种方式创建了一个近乎无限的循环,否则我不明白它怎么可能那么慢。

新规则:

<rule name="Rule" stopProcessing="true">
<match url="^Product/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)?[/]?(.+)?$"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="/Product/index.php?a={R:1}&amp;b={R:2}&amp;c={R:3}&amp;d={R:4}&amp;e={R:5}&amp;f={R:6}&amp;{R:7}" appendQueryString="true"/>
</rule>

最新更新