使用 Post 方法调用 REST WS 时,IIS 8.5 在生产中抛出 400 错误请求

使用 Post 方法调用 REST WS 时,IIS 8.5 在生产中抛出 400 错误请求

我有一个奇怪的问题。下面让我一步一步详细解释一下:

  1. 我有一个供应商开发了 REST WS(使用 WCF 制作)用于与 MS CRM 同步数据。

  2. 我开发了一个 Windows 服务,它从数据库中提取要同步的批量数据,然后使用 Post 方法将其作为 JSON 对象传递给此 Web 服务。Windows 服务部署在其中一个节点上。

  3. 我遇到的问题从未在开发、QA、UAT 或暂存环境中发生过。它只存在于生产环境中。

  4. 在生产中,应用程序运行一段时间后开始抛出 400 Bad request 错误。然后,直到我们重新启动站点或重置应用程序池标识,IIS 才会继续抛出 400 Bad request 错误。当我们重新启动站点或应用程序池时,失败的相同请求开始获得成功响应。它像这样运行了一段时间,然后又开始出现 400 错误。

  5. 托管 Web 服务的环境是 Win Server 2012,2 节点负载平衡环境。WS 部署在两个节点的端口 8080 上,并配置为在 .Net 4.0 下运行。

  6. 我在 Windows 服务日志(这些 WS 的客户端)中收到以下错误。

System.Net.WebException:远程服务器返回错误:(400)错误请求。在 SspToCrmSynchronizationService.Helpers.CrmWrapperWsHelper.CallService(String data, String url, String method, String userName, String password, String contentType) 在 CrmWrapperWsHelper.cs:第 79 行 在 SspToCrmSynchronizationService.Helpers.CrmWrapperWsHelper.CallDocumentCreateService(String data) 在 CrmWrapperWsHelper.cs:第 20 行 在 SspToCrmSynchronizationService.Process.CommonOperations.GenerateJsonAndInvokeDocCreateWS(Int64 appRefNo, Application app) 在 CommonOperations.cs:第 52 行 在 SspToCrmSynchronizationService.Process.SequentialProcess.Process(List`1 appList, DatabaseHelper dbHelperForChildTask, CancellationToken ct) 在 SequentialProcess.cs:第 88 行

  1. 首先,我们检查了 IIS 日志,发现 IIS 在短短几百毫秒内就返回了 400 错误。我们怀疑它没有到达 WS 应用程序,因为应用程序根本没有记录任何内容,尽管记录请求是供应商在 WS 代码中做的第一件事。

  2. 其次我们使用Fiddler捕获请求和响应,得到如下结果:

    HTTP/1.1 400 Bad Request
    Cache-Control: private
    Content-Length: 1647
    Content-Type: text/html
    Server: Microsoft-IIS/8.5
    X-ASpNet-Version: 4.0.30319
    X-Powered-By: ASP.Net
    Date: Tue, 17 Oct 2017 07:14:26 GMT
    

Fiddler 日志

  1. 然后我们检查了 IIS Httperr.log。在日志中我们发现部分请求有以下内容,但并非所有失败的请求都有以下内容。似乎什么都没有。

2017-07-07 03:32:45 10.102.2.52 63726 10.102.2.52 8080 - - - - - Timer_ConnectionIdle -
2017-07-08 22:46:55 10.102.2.52 50916 10.102.2.52 8080 - - - - - Timer_ConnectionIdle - 2017-07-08 22:55:09 10.102.2.52 51004 10.102.2.52 8080 - - - - - Timer_ConnectionIdle -

  1. 然后我们在 IIS 中将失败跟踪日志配置为 400,当抛出此 400 错误时,跟踪日志中会收到一条警告。出于保密协议和安全原因,我已从图像中删除部分数据。

IIS 失败跟踪日志 400 错误请求

基本上警告详细信息如下:

124. MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName="ManagedPipelineHandler", 
Notification="EXECUTE_REQUEST_HANDLER", 
HttpStatus="400", 
HttpReason="Bad Request", 
HttpSubStatus="0", 
ErrorCode="The operation completed successfully. (0x0)",
ConfigExceptionInfo=""
  1. 之后我比较了一个错误案例和一个成功案例。下面是图片。

错误和成功案例

我不知道是什么原因造成的(根本原因),如何解决,以及为什么它最初可以工作,但过了一段时间就不工作了。任何帮助都将不胜感激。

答案1

我们需要了解它是如何工作的,存在相当多的错误:

  1. 我们以 JSON 格式传递日期时间值。在我们的案例中,当 WS 容器(IIS 和 WCF)尝试将 DateTime 字段传递给应用程序时,在 WS 端 DateTime 值会引发一些解析错误,但转换失败。我相信这可能是由于语言环境造成的。我们通过在 WS 接受的 JSON 中将日期时间更改为字符串来修复此问题。

  2. 第二个问题是我们的供应商使用 WCF 技术来创建 Rest API。WCF 的一个行为是,如果来自客户端的请求导致 WS 容器中发生致命异常,则 IIS 会将此客户端注册到阻止列表中,并且不会将此客户端的请求转发到应用程序,直到 IIS 重新启动完成。IIS 会不断向我们返回错误请求状态消息。

相关内容