У меня странная проблема. Позвольте мне подробно объяснить ниже, шаг за шагом:
У меня поставщик разработал REST WS (сделанный с использованием WCF) для синхронизации данных с MS CRM.
Я разработал службу Windows, которая извлекает пакеты данных для синхронизации из базы данных, а затем передает их этим веб-службам с помощью метода Post в качестве объектов JSON. Служба Windows развернута на одном из узлов.
Проблема, с которой я сталкиваюсь, никогда не возникала в Dev, QA, UAT или в промежуточной среде. Это уникально только для производственной среды.
В процессе производства приложение какое-то время работает, а затем начинает выдавать ошибку 400 Bad request. Затем, пока мы не перезапустим сайт или не сбросим идентификатор пула приложений, IIS будет выдавать 400 ошибок неверного запроса. Когда мы перезапускаем сайт или пул приложений, те же запросы, которые были неудачными, начинают получать успешные ответы. Это работает какое-то время, а затем снова 400 начинает происходить.
Среда, в которой размещаются веб-службы, представляет собой среду Win Server 2012 с двухузловой балансировкой нагрузки. WS развернут на порту 8080 на узлах Boht и настроен для работы под .Net 4.0.
Я получил следующую ошибку в моем журнале службы Windows, который является клиентом для этих WS.
System.Net.WebException: удаленный сервер вернул ошибку: (400) неверный запрос. в SspToCrmSynchronizationService.Helpers.CrmWrapperWsHelper.CallService (строковые данные, строковый URL-адрес, строковый метод, строковое имя пользователя, строковый пароль, String contentType) в CrmWrapperWsHelper.cs: строка 79 на SspToCrmSynchronizationService.CrapperWallspervice.CrapperWallspervice.CrapperWallspervice.CrapperWallpers. : строка 20 в SspToCrmSynchronizationService.Process.CommonOperations.GenerateJsonAndInvokeDocCreateWS (Int64 appRefNo, приложение приложения) в CommonOperations.cs: строка 52 в SspToCrmSynchronizationService.Process.SequentialCrmSynchronizationService.Process.SequentialProcess.Process (List`1 appList) строка 88
Сначала мы проверили журналы IIS и обнаружили, что IIS возвращает ошибку 400 всего за несколько 100 мс. Мы подозреваем, что это не доходит до приложения 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
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 -
В основном детали предупреждения выглядят следующим образом:
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=""
Я понятия не имею, что вызывает это (основная причина) и как решить эту проблему, и почему она работает изначально и не работает через некоторое время. Любая помощь будет высоко ценится.
Нам нужно понять, как это работает, ошибок было довольно много:
Мы передавали значение datetime в JSON. В конце WS значение DateTime вызывало некоторые ошибки синтаксического анализа, когда контейнер WS в нашем случае (IIS и WCF) пытался передать поле DateTime приложению, не выполняя преобразование. Я считаю, что это могло быть связано с местными условиями. Мы исправили это, изменив datetime на строку в принятом WS JSON.
Вторая проблема заключалась в том, что наш поставщик использовал WCF в качестве технологии для создания Rest API. Одно из поведений WCF состоит в том, что если запрос от клиента вызывает фатальное исключение в контейнере WS, IIS зарегистрирует этого клиента в списке блокировки и не будет пересылать запрос от этого клиента приложению до тех пор, пока не будет перезапущен IIS. IIS будет продолжать возвращать нам сообщение о статусе неверного запроса.