【发布时间】:2012-03-09 15:06:13
【问题描述】:
我可以做些什么来使 X509 性能更好并遵循 new-channel-each-request 最佳实践,或者这种缓慢的协商是否是使用 X509 实现 WCF 安全性的固有缺点?
对于 tl;dr,请跳到末尾的 Update 3 以了解此内容的来源。
WCF 通道的最佳实践似乎是“重用 ChannelFactory,但为每个请求创建一个新通道”,我一直都是这样做的。例如。 Single WCF channel performance vs multiple channels
我目前正在尝试使用 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<IManagerService>("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。如果服务器在客户端 exe 运行之间保持正常运行,那么初始协商成本在后续运行中消失,这很好。
更新 2: 可能与防火墙/防病毒无关,因为我在一个 VM 中尝试了这个,并且禁用了股票 XP 和防火墙,结果非常不一致。一次是可预测的(每次调用 400 毫秒),另一次是这些疯狂的停顿。
更新 3: 在浏览跟踪日志后,每次创建新频道时似乎耗时的服务器活动(以及导致偶尔暂停的活动)是这样的:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>0</EventID>
<Type>3</Type>
<SubType Name="Transfer">0</SubType>
<Level>255</Level>
<TimeCreated SystemTime="2012-03-10T15:02:27.2968750Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{9e5e819b-e837-40b8-81b1-9f3c18e54595}" RelatedActivityID="{2faaac57-4e24-41ad-a3e5-85d81bddfa3b}" />
<Execution ProcessName="WcfCertExample" ProcessID="420" ThreadID="4" />
<Channel />
<Computer>MYCOMPUTER</Computer>
</System>
<ApplicationData></ApplicationData>
</E2ETraceEvent>
日志还显示:相关活动名称:流程操作“http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue”。
因此,如果有人对为什么这可能会持续暂停 17.5 秒以及它是否总是会正常花费 250 毫秒有任何想法,那么您将回答我的问题!
【问题讨论】:
-
我也见过stackoverflow.com/questions/1065182/…,但这并不真正适用于netTcpBinding。
-
基于证书的安全性不会导致此延迟。问题一定出在其他地方,很可能是网络级别的问题或检查证书的有效性。
-
这些是从文件系统加载的自我证书,并且 CertificateValidationMode 设置为 none,所以我不确定这是否排除了证书有效性检查的原因。我会在一些不同的机器上试试这个。
-
如果有人在更新 3 之后有想法并需要更多信息,请尽管询问。
-
没有答案的相关 MS 问题:social.msdn.microsoft.com/Forums/ar/wcf/thread/…
标签: c# .net wcf x509certificate