Является ли использование X509 для безопасности WCF медленным по своей сути с новым каналом для каждого запроса?

Могу ли я что-нибудь сделать, чтобы X509 работал лучше иследовал передовой практике нового канала для каждого запроса, или это медленное согласование является неотъемлемым недостатком использования X509? для безопасности WCF?

Для tl;dr перейдите к Обновление 3в конце для источника этого.

Лучшей практикой для каналов WCF является «повторное использование ChannelFactory, но создание нового канала для каждого запроса», и я всегда поступал так. Например. Производительность одного канала WCF по сравнению с несколькими каналами

В настоящее время я экспериментирую с использованием сертификатов X509 в качестве учетных данных безопасности, и CreateChannel каждый раз занимает много времени (15 секунд+). Повторное использование канала впоследствии дает хорошую производительность (если я правильно понимаю, потому что симметричные ключи используются после первоначальной аутентификации с открытым/закрытым ключом, которая происходит при вызове CreateChannel), но это плохая практика.

На стороне сервера:

var managerCertificate = new X509Certificate2(@"Manager.pfx", "");
var host = new ServiceHost(typeof(ManagerService));
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
host.Credentials.ServiceCertificate.Certificate = managerCertificate;
host.Open();
Console.ReadLine();

На стороне исполнителя (медленно выполнять каждый запрос):

var workerCertificate = new X509Certificate2(@"Worker.pfx", "");
var cfact = new ChannelFactory("client");
cfact.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
cfact.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
cfact.Credentials.ClientCertificate.Certificate = workerCertificate;
for (int i = 0; i < 10; i++)
{
    using (IManagerService channel = cfact.CreateChannel()
    {
         Console.WriteLine(channel.GetMyData("test data" + i));
    }
}

И если я перенесу вызов CreateChannel за пределы цикла for для его повторного использования, только первый запрос займет существенное время.

Кроме того, я использую NetTcpBinding.

Обновление 1:Краткая выборка результатов:

0: 546.875ms
1: 281.25ms
2: 281.25ms
3: 17484.375ms
4: 250ms
5: 234.375ms
6: 250ms
7: 250ms
8: 265.625ms
9: 250ms

250 мс — это не слишком ужасные накладные расходы на вызов (хотя и огромные по сравнению с повторным использованием канала), 17 секунд), которые различаются по частоте, иногда 1 к 3. Если сервер остается в рабочем состоянии между запусками клиентского исполняемого файла, то первоначальная стоимость согласования исчезает при последующих запусках, так что это хорошо.

Обновление 2:Предположительно, это не связано с брандмауэром/антивирусом, так как я попробовал это внутри виртуальной машины со стандартной XP и отключенным брандмауэром и получил крайне противоречивые результаты. Один раз предсказуемо (400мс за звонок), другой эти сумасшедшие паузы.

Обновление 3:После просмотра журналов трассировки выяснилось, что при создании нового канала каждый раз требуется много времени (и активность, которая является причиной периодической паузы):


  
    0
    3
    0
    255
    
    
    
    
    
    MYCOMPUTER
  
  

в журнале также говорится: Название связанной активности: Действие процесса «http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue».

Итак, если у кого-то есть какие-либо идеи о том, почему это может постоянно приостанавливаться на 17,5 секунд и всегда ли это будет стоить 250 мс в обычном режиме, тогда вы будете отвечать на мой вопрос!

6
задан Community 23 May 2017 в 10:24
поделиться