2010-12-06 2 views
4

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

Я столкнулся с вызовом службы WCF, размещенной в IIS7, используя nettcp, по сравнению с вызовом интерфейса удаленного доступа, размещенного в консольном приложении. Служба 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(); 

Файл web.config для узла IIS выглядит следующим образом:

<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 millisconds завершить (я не мог загрузить Animage, вот один acivity след из журнала)

От: Обработка сообщения 5. Передача 3/12/2010 15: 35: 58.861
Граница деятельности. Start 3/12/2010 15: 35: 58.861
Получено сообщение по каналу. Информация 3/12/2010 15: 35: 58.861
To: Выполнение 'Ria.Spike.News.Newss.NewsService.GetNews' Transfer 3/12/2010 15: 35: 58.864
Граница деятельности. Suspend 3/12/2010 15: 35: 58.864
От: Выполнение 'Ria.Spike.News.Newss.NewsService.GetNews' Transfer 3/12/2010 15: 35: 58.864
Граница деятельности. Резюме 3/12/2010 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:

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);  
    } 
} 
+0

Было бы интересно узнать, есть ли штраф за запуск для версии WCF.Не могли бы вы попробовать запустить, где sw не запускается, пока вызов не будет сделан хотя бы один раз и опубликует результаты? – 2010-12-06 23:00:59

ответ

9

Это тестирует последовательный, синхронный, только звонки. Служба WCF, обслуживаемая IIS, предоставляет больше инфраструктуры для обработки более высокой нагрузки и, скорее всего, не удастся выполнить дистанцию ​​для теста высокой нагрузки (один с множеством параллельных подключений).

Удаленная конечная точка также может быть размещена в IIS, хотя для получения тех же преимуществ. WCF также можно разместить в консоли. Вы действительно сравниваете яблоки с апельсинами здесь.

Смежные вопросы