问题描述

404(找不到请求资源)错误是一种最常见的web服务器报错,最近在启用URL Rewrite模块的服务器上遇到一个比较特殊的404错误,所请求的资源在正确的位置,但是从客户端请求始终报错404。
出错环境中服务器分为前端服务器和后端服务器,均为Windows Server 2008 R2 (IIS 7.5),前端服务器通过URL Rewrite模块将请求改写为真正的后端服务器请求,请求后端服务器资源并回复给客户端。
客户端请求以下文件时报404错误。
http://localhost/abc.svc

URL Rewrite的目标路径是http://backgroundserver/abc.svc,在前段服务器上直接请求该链接没有问题。

问题调试

我们通过IIS内置错误追踪机制failed request tracing来查看该错误。在该网站的web.config中<configuration>\<system.webServer>节点下添加如下配置,这个配置节点的意思是追踪服务器所有返回为404的请求,记录所有模块处理过程的详细信息。

<tracing>
            <traceFailedRequests>
                <add path="*">
                    <traceAreas>
                        <add provider="ASP" verbosity="Verbose" />
                        <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
                        <add provider="ISAPI Extension" verbosity="Verbose" />
                        <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,Rewrite,RequestRouting" verbosity="Verbose" />
                    </traceAreas>
                    <failureDefinitions timeTaken="00:00:00" statusCodes="404" />
                </add>
            </traceFailedRequests>
        </tracing>
    </system.webServer>
</configuration>

也可以通过IIS Manager界面来添加这个配置。具体可以参考http://www.iis.net/learn/troubleshoot/using-failed-request-tracing/troubleshooting-failed-requests-using-tracing-in-iis
配置了failed request tracing之后,再次请求该链接并得到404报错,之后到failed request tracing默认路径下找到生成的日志文件,通过IE打开。
C:\inetpub\logs\FailedReqLogFiles\W3SVC1\

在该日志summary中有两个关键信息值得注意,

  • 出错模块为ServiceModel-4.0
  • 出错阶段为AUTHENTICATE_REQUEST

 

以下是一个正常的404报错,可以看到正常情况下

  • 出错模块为IIS Web Core
  • 出错阶段为MapRequestHandler

接下来我们了解一下URL Rewrite的工作原理。参考下图,

URL Rewrite模块在Begin Request阶段就会将请求按照配置的规则改写。之后交给后续模块继续处理。Authenticate Request阶段负责对请求进行认证。之后会到Map Handler阶段,这时Application Request Routing模块会检查该请求是否需要forward给其他服务器,如果需要则向其他服务器发送请求,并将相应结果交给后续模块,最终回传给客户端。

我们的这个404报错居然处在了Authenticate Request阶段,说明Application Request Routing模块还没有来的及请求后台服务器就报了404错误。

通过failed request tracing日志的详细日志也可以看到相应的出错过程。

解决方案

现在问题发生的原因明确的了,是ServiceModel-4.0模块在Authenticate_Request阶段截获了请求并验证该资源是否存在于本地服务器,由于资源在后台服务器,需要借助URL Rewrite和Application Request Routing模块,因此报了404错误。
要解决该问题,我们到IIS Manager里面找到处理该模块的Handler Mapping。由于我们在前段服务器网站只需要用URL Rewrite将请求改到后端服务器,不需要该模块来处理svc文件请求,因此我们可以直接将其删除。

再次请求之前出错的链接,得到了正确的页面,404问题解决了。

 

希望以上内容对你有所帮助。

 

 

 

posted on 2013-04-28 10:28  微软互联网开发支持  阅读(3868)  评论(2编辑  收藏  举报