IIS 8.5 在使用 Post 方法呼叫 REST WS 時在生產中拋出 400 Bad request
我有一個奇怪的問題。讓我在下面一步一步詳細解釋:
- 我有一個供應商開發了 REST WS(使用 WCF 製作)用於與 MS CRM 同步數據。
- 我開發了一個 Windows 服務,它從數據庫中獲取要同步的批次數據,然後使用 Post 方法將其作為 JSON 對像傳遞給這個 Web 服務。Windows 服務部署在其中一個節點上。
- 我面臨的問題從未在 Dev、QA、UAT 或暫存環境中發生。它僅適用於生產環境。
- 在生產中,應用程序工作了一段時間,然後開始拋出 400 Bad request 錯誤。然後,直到我們重新啟動站點或重置應用程序池標識,IIS 一直拋出 400 Bad request 錯誤。當我們重新啟動站點或應用程序池時,失敗的相同請求開始獲得成功的響應。它可以像這樣工作一段時間,然後再開始發生 400 次。
- 託管 Web 服務的環境是 Win Server 2012,2 節點負載平衡環境。WS 部署在兩個節點的 8080 埠上,並配置為在 .Net 4.0 下執行。
- 我在作為這些 WS 客戶端的 Windows 服務日誌中收到以下錯誤。
System.Net.WebException:遠端伺服器返回錯誤:(400)錯誤請求。在 CrmWrapperWsHelper.cs 中的 SspToCrmSynchronizationService.Helpers.CrmWrapperWsHelper.CallService(String data, String url, String method, String userName, String password, String contentType):CrmWrapperWsHelper.cs 中 SspToCrmSynchronizationService.Helpers.CrmWrapperWsHelper.CallDocumentCreateService(String data) 的第 79 行:CommonOperations.cs 中 SspToCrmSynchronizationService.Process.CommonOperations.GenerateJsonAndInvokeDocCreateWS(Int64 appRefNo, Application app) 的第 20 行:SspToCrmSynchronizationService.Process.SequentialProcess.Process(List`1 appList, DatabaseHelper dbHelperForChildTask, CancellationToken ct) 在 SequentialProcess.cs 中的第 52 行:第 88 行
- 首先,我們檢查了 IIS 日誌,發現 IIS 在短短 100 毫秒內就返回了 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_Idle 2017-07-08 22:55:09 10.102.2.52 51004 10.102.2.52 8080 - - - - - Timer_ConnectionIdle -
- 比我們在 IIS 中將 Failed Traced Log 配置為 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=""
- 之後,我比較了一個錯誤案例和一個成功案例。下面是圖片。
我不知道是什麼導致了這個(根本原因)以及如何解決這個問題以及為什麼它最初可以工作而一段時間後無法工作。任何幫助將不勝感激。
我們需要了解它是如何工作的,有很多錯誤:
- 我們在 JSON 中傳遞了一個日期時間值。在 WS 端,當嘗試將 DateTime 欄位傳遞給應用程序的 WS 容器(IIS 和 WCF)在執行轉換時失敗時,DateTime 值會引發一些解析錯誤。我相信這可能是由於語言環境。我們通過將日期時間更改為 WS 接受的 JSON 中的字元串來修復它。
- 第二個問題是我們的供應商使用 WCF 作為一種技術來創建 Rest API。WCF 的一種行為是,如果來自客戶端的請求導致 WS 容器中發生致命異常,則 IIS 將在阻止列表中註冊該客戶端,並且在 IIS 重新啟動完成之前不會將來自該客戶端的請求轉發到應用程序。IIS 將不斷向我們返回錯誤請求狀態消息。