我正在尝试评估在新系统中使用哪种通信技术,现在看起来Remoting是我们唯一的选择,因为WCF的性能非常糟糕. 与调用控制台应用程序中托管的远程接口相比,我使用nettcp对IIS7中托管的WCF服
与调用控制台应用程序中托管的远程接口相比,我使用nettcp对IIS7中托管的WCF服务进行了基准测试. WCF服务需要大约4.5秒来执行1000个请求,在端点上同步(它只返回一个对象的新瞬时).远程客户端采用< 0.5秒执行相同的任务. 这是WCF客户端代码:
public class TcpNewsService : INewsService { private INewsService _service = null; Lazy<ChannelFactory<INewsService>> _newsFactory = new Lazy<ChannelFactory<INewsService>>(() => { var tcpBinding = new NetTcpBinding { //MaxBufferPoolSize = int.MaxValue, //MaxBufferSize = int.MaxValue, //MaxConnections = int.MaxValue, //MaxReceivedMessageSize = int.MaxValue, PortSharingEnabled=false, TransactionFlow = false, ListenBacklog = int.MaxValue, Security = new NetTcpSecurity { Mode = SecurityMode.None, Transport = new TcpTransportSecurity { ProtectionLevel = System.Net.Security.ProtectionLevel.None, ClientCredentialType = TcpClientCredentialType.None }, Message = new MessageSecurityOverTcp { ClientCredentialType = MessageCredentialType.None } }, ReliableSession = new OptionalReliableSession { Enabled = false } }; EndpointAddress endpointAddress = new EndpointAddress("net.tcp://localhost:8089/NewsService.svc"); return new ChannelFactory<INewsService>(tcpBinding, endpointAddress); }); public TcpNewsService() { _service = _newsFactory.Value.CreateChannel(); ((ICommunicationObject)_service).Open(); } public List<NewsItem> GetNews() { return _service.GetNews(); } }
一个简单的控制台应用程序来调用客户端代码:
var client = new TcpNewsService(); Console.WriteLine("Getting all news"); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < 1000; i++) { var news = client.GetNews(); } sw.Stop(); Console.WriteLine("Finished in " + sw.Elapsed.TotalSeconds); Console.ReadLine();
IIS主机的web.config文件如下所示:
<system.serviceModel> <services> <service behaviorConfiguration="NewsServiceBehavior" name="RiaSpike.News.Service.NewsService"> <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpBinding" contract="RiaSpike.News.Types.INewsService"> </endpoint> <endpoint address="http://localhost:8094/NewsService.svc" binding="basicHttpBinding" bindingConfiguration="httpBinding" contract="RiaSpike.News.Types.INewsService"> </endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="NewsServiceBehavior"> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <basicHttpBinding> <binding name="httpBinding"> <security mode="None"> <transport clientCredentialType="None" /> </security> </binding> </basicHttpBinding> <netTcpBinding> <binding name="tcpBinding" portSharingEnabled="false"> <security mode="None"> <transport clientCredentialType="None" /> <message clientCredentialType="None" /> </security> <reliableSession enabled="false" /> </binding> </netTcpBinding> </bindings>
IIS中托管的服务类:
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single, AddressFilterMode = AddressFilterMode.Any )] public class NewsService : MarshalByRefObject, INewsService { public List<NewsItem> GetNews() { return new List<NewsItem> { new NewsItem { Descripion = "The Description", Id = 1, Title = "The Title"} }; } }
我已经跟踪了WCF活动,并且已经看到该过程大约需要5毫秒才能完成(我无法上传动画,这里是日志中的一个动态跟踪)
来自:处理消息5.转移3/12/2010 15:35:58.861
活动边界.开始于2010年3月12日15:35:58.861
通过频道收到消息.信息3/12/2010 15:35:58.861
收件人:执行’Ria.Spike.News.INewsService.GetNews’Transfer 3/12/2010 15:35:58.864
活动边界.暂停3/12/2010 15:35:58.864
来自:执行’Ria.Spike.News.INewsService.GetNews’Transfer 3/12/2010 15:35:58.864
活动边界.简历2010年3月12日15:35:58.864
通过频道发送消息信息3/12/2010 15:35:58.866
活动边界.停止3/12/2010 15:35:58.866
这是不是很好:s
这是此示例中使用的远程处理代码.
var iserver = (INewsService)Activator.GetObject(typeof(INewsService), "tcp://127.0.0.1:9000/news"); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < 1000; i++) { var news = iserver.GetNews(); } sw.Stop(); Console.WriteLine("Finished in " + sw.Elapsed.TotalSeconds); Console.ReadLine();
以及在IIS中托管此远程通道的TCP端点:
public class Global : System.Web.HttpApplication { private TcpServerChannel _quote; protected void Application_Start(object sender, EventArgs e) { _quote = new TcpServerChannel(9000); if (ChannelServices.RegisteredChannels.Length ==0) { ChannelServices.RegisterChannel(_quote, false); } RemotingConfiguration.RegisterWellKnownServiceType( typeof(NewsService), "news", WellKnownObjectMode.SingleCall); _quote.StartListening(null); } }这仅测试顺序,同步,调用. IIS托管的WCF服务提供了更多的基础架构来处理更高的负载,并且很可能超出高负载测试(具有大量并发连接的测试)的远程处理.
远程端点也可以在IIS中托管,以获得相同的优势. WCF也可以托管在控制台中.你真的在这里比较苹果和橘子.