IIS8 RewriteModule / URLRewrite 极慢
IIS8 RewriteModule / URLRewrite Extremely Slow
我是 运行 一个在 Windows Server 2012 上安装 IIS8 的网站。我正在尝试确定导致 IIS CPU 使用率高的原因(通常是 50% 或更多 CPU IIS 使用)。服务器全天每秒接收大约 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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}&{R:7}" appendQueryString="true"/>
</rule>
我定义匹配项 URL 的方式是否导致处理时间过长?如果某些匹配网址使用许多 parent/child 类别(最多 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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}" appendQueryString="true"/>
</rule>
我在你的正则表达式中删除了不必要的 \?
检查,因为 <match url
中的模式正在检查 URL 没有查询字符串,所以 ?
检查是多余的在你的正则表达式中。
我检查了我的 PC,它确实运行得更快,但你需要仔细检查它是否保持相同的功能
我进行了大量测试并将规则更改为以下内容。这导致 CPU 下降到 1%,之前的 100 秒完成时间下降到大约 50 毫秒。
我仍然不明白这是怎么可能的 - 这是一台 4 CPU/8-core 机器,有 48GB 内存,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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}&{R:7}" appendQueryString="true"/>
</rule>
我是 运行 一个在 Windows Server 2012 上安装 IIS8 的网站。我正在尝试确定导致 IIS CPU 使用率高的原因(通常是 50% 或更多 CPU IIS 使用)。服务器全天每秒接收大约 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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}&{R:7}" appendQueryString="true"/>
</rule>
我定义匹配项 URL 的方式是否导致处理时间过长?如果某些匹配网址使用许多 parent/child 类别(最多 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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}" appendQueryString="true"/>
</rule>
我在你的正则表达式中删除了不必要的 \?
检查,因为 <match url
中的模式正在检查 URL 没有查询字符串,所以 ?
检查是多余的在你的正则表达式中。
我检查了我的 PC,它确实运行得更快,但你需要仔细检查它是否保持相同的功能
我进行了大量测试并将规则更改为以下内容。这导致 CPU 下降到 1%,之前的 100 秒完成时间下降到大约 50 毫秒。
我仍然不明白这是怎么可能的 - 这是一台 4 CPU/8-core 机器,有 48GB 内存,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}&b={R:2}&c={R:3}&d={R:4}&e={R:5}&f={R:6}&{R:7}" appendQueryString="true"/>
</rule>