Прошу прощения за длину сообщения, но есть много вещей, которые могут вызвать мою ситуацию, и я попытался включить все изменения настроек, которые я сделал на основе других сообщений. Короче говоря, служба My WCF, похоже, ограничена 3 или 4 одновременными клиентскими запросами за раз. Если я установлю максимальное количество рабочих процессов для пула приложений выше (около 10) или установлю для поведения службы ConcurrencyMode значение Multiple, я получу гораздо лучшую пропускную способность (в несколько раз быстрее). Тем не менее, они кажутся обходными путями к реальной проблеме, принося с собой свои собственные проблемы. Я ошибаюсь, или IIS должен иметь возможность запускать множество экземпляров (десятки или более) моей службы WCF внутри одного рабочего процесса для обработки нагрузки? Я просто знаю, что где-то отсутствует настройка, но я не могу ее найти.
Редактировать. Пока я пробовал предложенные варианты, я понял, что мои математические расчеты не соответствуют пропускной способности. С циклом ForEach я получаю расчетную параллельную обработку на сервере в 20 секунд (на продолжительность задачи * количество задач / общее время выполнения). Это все еще кажется низким для фактической выполняемой работы (сон 10 секунд), но уже не смехотворно низким.
Второе редактирование: я отметил комментарий @Pablo как ответ, потому что его ответ и его ссылка дали мне информацию, позволяющую значительно повысить производительность (я думаю, примерно в 3 раза). Однако я хотел бы задать дополнительный вопрос: каковы разумные ожидания для обработки одновременных запросов в WCF/IIS? Предполагая, что ЦП, память и ввод-вывод не являются узкими местами, каков практический предел/ожидание (на ЦП) для обработки запросов? То, что я ищу, — это эмпирическое правило, которое говорит мне, что я, вероятно, не получу больше больших приростов без добавления процессоров (или рабочих процессов). Спасибо еще раз.
(В Windows 2008 Server, размещенном в IIS, 1 процессор)
Конфигурация службы WCF (сокращенно):
<?xml version="1.0"?>
<configuration>
<configSections>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
<service name="FMHIRWCFSvc.IRService" behaviorConfiguration="IRServiceBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="FMHIRWCFSvc.IIRService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="Binding1" maxReceivedMessageSize="104857600">
<readerQuotas maxArrayLength="104857600"/>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="IRServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling
maxConcurrentCalls = "500"
maxConcurrentSessions = "500"
maxConcurrentInstances = "500"
/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<applicationSettings>
<FMHIRWCFSvc.Properties.Settings>
<setting name="FMHIRWCFSvc_ir_dev_websvc_IRWebService40" serializeAs="String">
<value>http://ir-dev-websvc/imageright.webservice/IRWebService40.asmx</value>
</setting>
</FMHIRWCFSvc.Properties.Settings>
</applicationSettings>
<system.net>
<connectionManagement>
<add address="*" maxconnection="500"/>
</connectionManagement>
</system.net>
</configuration>
Конфигурация клиента (сокращенно):
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IIRService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://{myserveraddress}/FMHIRWCFSvc/IRService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IIRService"
contract="wcf_local.IIRService" name="BasicHttpBinding_IIRService" />
</client>
</system.serviceModel>
<system.net>
<connectionManagement>
<add address="*" maxconnection="500"/>
</connectionManagement>
</system.net>
</configuration>
Вызов клиентского метода:
static void WCFTesting()
{
ConcurrentQueue<Exception> exceptionList = new ConcurrentQueue<Exception>();
int[] taskList = new int[250];
Parallel.ForEach(taskList, theTask =>
{
try
{
// Create the WCF client
BasicHttpBinding binding = new BasicHttpBinding {
Security = { Mode = BasicHttpSecurityMode.Transport },
SendTimeout = TimeSpan.FromSeconds(20)
};
EndpointAddress endpointAddress = new EndpointAddress("https://{myserveraddress}/FMHIRWCFSvc/IRService.svc");
IRServiceClient wcfClient = new IRServiceClient(binding, endpointAddress);
// Call wcf service method that sleeps 10 seconds and returns
wcfClient.TestCall();
}
catch (Exception exception) {
// Store off exceptions for later processing
exceptionList.Enqueue(exception);
}
});
}
Код службы WCF:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
...
public string TestCall()
{
Thread.Sleep(10000);
return null;
}
Спасибо за любую информацию или предложения!