我有一个奇怪的问题。下面让我一步一步详细解释一下:
我有一个供应商开发了 REST WS(使用 WCF 制作)用于与 MS CRM 同步数据。
我开发了一个 Windows 服务,它从数据库中提取要同步的批量数据,然后使用 Post 方法将其作为 JSON 对象传递给此 Web 服务。Windows 服务部署在其中一个节点上。
我遇到的问题从未在开发、QA、UAT 或暂存环境中发生过。它只存在于生产环境中。
在生产中,应用程序运行一段时间后开始抛出 400 Bad request 错误。然后,直到我们重新启动站点或重置应用程序池标识,IIS 才会继续抛出 400 Bad request 错误。当我们重新启动站点或应用程序池时,失败的相同请求开始获得成功响应。它像这样运行了一段时间,然后又开始出现 400 错误。
托管 Web 服务的环境是 Win Server 2012,2 节点负载平衡环境。WS 部署在两个节点的端口 8080 上,并配置为在 .Net 4.0 下运行。
我在 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 行
首先,我们检查了 IIS 日志,发现 IIS 在短短几百毫秒内就返回了 400 错误。我们怀疑它没有到达 WS 应用程序,因为应用程序根本没有记录任何内容,尽管记录请求是供应商在 WS 代码中做的第一件事。
其次我们使用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
- 然后我们检查了 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 -
- 然后我们在 IIS 中将失败跟踪日志配置为 400,当抛出此 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
我们需要了解它是如何工作的,存在相当多的错误:
我们以 JSON 格式传递日期时间值。在我们的案例中,当 WS 容器(IIS 和 WCF)尝试将 DateTime 字段传递给应用程序时,在 WS 端 DateTime 值会引发一些解析错误,但转换失败。我相信这可能是由于语言环境造成的。我们通过在 WS 接受的 JSON 中将日期时间更改为字符串来修复此问题。
第二个问题是我们的供应商使用 WCF 技术来创建 Rest API。WCF 的一个行为是,如果来自客户端的请求导致 WS 容器中发生致命异常,则 IIS 会将此客户端注册到阻止列表中,并且不会将此客户端的请求转发到应用程序,直到 IIS 重新启动完成。IIS 会不断向我们返回错误请求状态消息。