2012-02-08 3 views
0

У меня есть сам сервер F # WCF, который используется для возврата кэшированных данных в наше приложение. Объем данных может варьироваться от одной строки до десятков тысяч. Из-за больших различий в данных я установил значения в app.config для обработки очень больших элементов данных. Все работало нормально до недели назад, когда что-то сломалось, и сервер просто прекратил работать. Мне потребовалось несколько дней, чтобы получить вещи, и я никогда не понял, что случилось. Я использовал служебную утилиту и изменил настройки до тех пор, пока я снова не заработал. Проблема в том, что она добавила 1,2 секунды задержки, которых раньше не было. Я настраивал настройки снова и снова и читал каждую статью, которую я могу найти, и ничего не помогает. У меня есть настройки для netTcp и Ws, но я использую настройки netTcp. (Могут быть некоторые настройки, которые не обязательно должны быть там, но я хотел поставить все это здесь, если есть некоторые конфликты, о которых я не знаю.) Вот файл app.config:WCF Latency Issue

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding name="NetTcpBinding_IPrevisionServer" closeTimeout="00:01:00" 
      openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" 
      hostNameComparisonMode="StrongWildcard" 
      maxBufferSize="2147483647" 
      maxBufferPoolSize="2147483647" 
      maxReceivedMessageSize="2147483647"> 
      <readerQuotas maxDepth="2147483647" 
      maxStringContentLength="2147483647" 
      maxArrayLength="2147483647" 
      maxBytesPerRead="2147483647" 
      maxNameTableCharCount="2147483647" /> 
      <security mode="Transport"> 
      <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
      <message clientCredentialType="Windows" /> 
      </security> 
     </binding> 
     </netTcpBinding> 
     <wsHttpBinding> 
     <binding name="WSHttpBinding_IPrevisionServer" closeTimeout="00:01:00" 
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
      bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
      maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" 
      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
      allowCookies="false"> 
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" 
       maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
      <reliableSession ordered="true" inactivityTimeout="00:10:00" 
       enabled="false" /> 
      <security mode="Message"> 
      <transport clientCredentialType="Windows" proxyCredentialType="None" 
       realm="" /> 
      <message clientCredentialType="Windows" negotiateServiceCredential="true" 
       algorithmSuite="Default" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="PrevisionSerializer" 
     name="PrevisionServer.PrevisionService"> 
     <endpoint address="net.tcp://192.168.101.100:2009/PrevisionService/tcp" 
      binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionServer" 
      contract="IPrevisionServer" name="NetTcpBinding_IPrevisionServer"> 
     </endpoint> 
     </service> 
    </services> 
    <client> 
     <endpoint address="http://192.168.101.100:2008/PrevisionService/ws/ws" 
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IPrevisionServer" behaviorConfiguration="ServiceViewEventBehavior" 
      contract="IPrevisionServer" name="WSHttpBinding_IPrevisionServer"> 
     <identity> 
      <userPrincipalName value="[email protected]" /> 
     </identity> 
     </endpoint> 
     <endpoint address="net.tcp://192.168.101.100:2009/PrevisionService/tcp" behaviorConfiguration="ServiceViewEventBehavior" 
      binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionServer" 
      contract="IPrevisionServer" name="NetTcpBinding_IPrevisionServer"> 
     <identity> 
      <userPrincipalName value="[email protected]" /> 
     </identity> 
     </endpoint> 
    </client> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="HttpGetMetadata"> 
      <serviceMetadata httpGetEnabled="true" /> 
     </behavior> 
     <behavior name="PrevisionSerializer"> 
      <dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" /> 
      <serviceTimeouts transactionTimeout="01:00:00" /> 
      <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" 
      maxConcurrentInstances="1000" /> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="ServiceViewEventBehavior"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    </system.serviceModel> 
    <system.diagnostics> 
    <trace autoflush="true" /> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="wcfTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WcfClientTrace.svclog" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 
</configuration> 

Я бы хотел использовать WCF, но, делая все это, меня заставляет задуматься, может быть, я должен смотреть на сырые сокеты вместо этого? Пожалуйста, дайте мне знать, есть ли другой код, который вы хотите увидеть, но это очень важно, поэтому я не хотел публиковать его.

UPDATE: Per Richard Blewett, я объясню, что я пытаюсь сделать, и любое руководство по наилучшему способу настройки было бы замечательным.

В основном, я перемещаю большую часть нашей бизнес-логики на сервер приложений, так как большая часть его сейчас содержится в хранимых процедурах SQL Server, и мы находим, что из-за сложности запросов SQL просто слишком медленно. Обращаясь к SQL, преобразовывая данные с использованием библиотек F # на сервере приложений, а затем кешируя его, я обнаружил, что могу отбросить время с 20-60 секунд на запрос до менее 3 после кэширования данных, хотя большая часть это связано с проблемой задержки, описанной выше. Я знаю, что в некоторых случаях может быть 3 секунды, но я знаю, что он может идти быстрее, поскольку он работал до этого, и в конечном итоге мы хотим, чтобы это было развернуто в облачном решении, тогда будет задействовано 1000 пользователей, поэтому я хочу, чтобы это быть в состоянии хорошо масштабироваться.

Тип данных, которые мы возвращаем, обычно составляет менее 10 столбцов, причем каждый из них обычно составляет строки менее 100 символов или десятичные знаки. Но данные будут иметь много строк, от нескольких сотен до десятков тысяч. Количество клиентов будет варьироваться от нескольких до 100 или более одновременно (хотя на данный момент клиентов очень мало). Приложение, которое будет развернуто на наших различных клиентских сайтах, позже будет развернуто в облачном решении.

Поскольку данные в основном используются для отчетности, большинство вызовов предназначены только для чтения данных, следовательно, кэширование. Обычно пользователь запускает отчет, изменяет параметр, затем снова запускает отчет, поэтому сразу же потребуется много данных, а затем ничего в секундах или минутах. Существуют некоторые процессы пакетного отчета, хотя пользователь будет запускать серию отчетов (часто сотни) подряд и, следовательно, будет представлять собой большое количество вызовов для данных, которые могут варьироваться от нескольких сотен строк до десятков тысяч одновременно.

Я надеюсь, что этого достаточно для продолжения. Еще раз спасибо!

+0

Просто: просто потяните app.config, который вы использовали неделю назад из управления версиями, и вместо этого используйте;) –

+0

readerQuotas дело с обработкой XML. Нет необходимости в таких больших значениях во всех атрибутах, особенно maxDepth. Вы также можете посмотреть в использовании messageEncoding = «Mtom». –

+0

500, я бы, но у меня не было тестового клиента в управлении версиями. :( – Erick

ответ

0

Если вы после скорости удалите все записи вокруг WSHttpBinding - это просто путающие вопросы.

MTOM только полезно, если вы используете текстовый XML для отправки бинарными интероперабельной образом - вы используете бинарный кодер с NetTcpBinding поэтому данные по проводам уже двоичная

Я подозреваю, что вы обратились по безопасности в службе, которая ранее была отключена, где вы видите разницу в производительности.

Бросок конфигурации при обслуживании может «заставить работать», но может вызвать большие проблемы позже. Например, вы установили время ожидания приема на час. Это означает, что если клиент не закрывает свой прокси-сервер, вам потребуется час, прежде чем ваша служба решит, что клиент не вернется и поэтому он будет поддерживать ресурсы сеанса для этого клиента в течение часа.

Если вы подробно расскажете о своих требованиях с точки зрения тайм-аутов, размеров сообщений и безопасности, мы можем помочь вам получить конфигурацию, которая соответствует вашим требованиям.

+0

Richard, спасибо за ваше время в работе над этим. Я добавил описание выше. Пожалуйста, дайте мне знать, если что-то еще вам нужно. Еще раз спасибо. – Erick

+0

Hi Erick - быстрый расчет показывает, что вы можете вернуть 40 МБ данных - убедитесь, что набор данных, который вы возвращаете, еще не вырос - таким образом, изменив профиль производительности? В противном случае - каковы ваши требования безопасности? Должны ли данные шифроваться? –

+0

Richard - Данные испытаний остались прежними. чтобы быть зашифрованным, по крайней мере, не сейчас. Будет вызван пользовательский вызов по умолчанию из клиентского приложения, поэтому он не беспокоится о AD или что-то в этом роде. – Erick