2010-12-06 39 views
4

新しいシステムで使用する通信技術を評価しようとしていますが、WCFのパフォーマンスがひどいため、Remotingが唯一の選択肢であるように見えます。Remotingと比べてWCFのパフォーマンスが遅いのはなぜですか?

私は、nettcpを使用してIIS7でホストされているWCFサービスの呼び出しをベンチマークしました。これは、コンソールアプリケーションでホストされているリモーティングインターフェイスを呼び出すことと比較しています。 WCFサービスは、エンドポイントで1000個の要求を実行するのに約4.5秒かかります(単純にオブジェクトの新しいインスタンスを返す)。リモートクライアントは、同じタスクを実行するために、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(); 
    } 
} 

とクライアントコードを呼び出すための単純なコンソールアプリケーション:IISホストの

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ファイルは次のようになります。

<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でホストされているサービスクラス:私はWCFの活動をトレースしているプロセスを見てきました

[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"} 
      }; 
    } 
} 

が完了するまでに約5 milliscondsを取る(私はアニメージュをアップロードすることができませんでした、ここではログから1つのacivityトレースです)

送信元:処理メッセージ5.転送3/12/2010 15:35:58.861
アクティビティの境界。開始2010/03/12 15:35:58.861
チャンネル経由でメッセージを受信しました。情報3/12/2010 15:35:58.861
To: 'Ria.Spike.News.INewsService.GetNews'を転送する。3/12/2010 15:35:58.864
アクティビティの境界。サスペンド3/12/2010 15:35:58.864
送信元: 'Ria.Spike.News.INewsService.GetNews'転送転送3/12/2010 15:35:58.864
アクティビティの境界。履歴書2010年3月12日15:35:58.864
チャネルを介してメッセージを送信しました。情報3/12/2010 15:35:58.866
アクティビティの境界。 35::2010年3月12日15を停止58.866

は恋愛小説家このされます。■

は、ここでは、この例で使用するリモートコードです。

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

WCFバージョンのスタートアップペナルティがあるかどうかを確認することは重要です。呼び出しが少なくとも1回行われて結果が送信されるまで、swが起動していない実行を試すことができますか? –

+0

こんにちはPeter、私は実際にstarupコストを解消するために1000回の呼び出しを2回呼び出しました。第1と第2の時差はごくわずかであった。 – gav

+0

リモート設定は何ですか? –

答えて

9

これは、同期、シーケンシャルテストは、コールのみ。 IISでホストされるWCFサービスは、より高い負荷を処理するためのより多くのインフラストラクチャを提供し、高負荷テスト(多数の同時接続があるもの)のリモート処理を実行する可能性があります。

同じ利点を得るために、リモートエンドポイントをIISでホストすることもできます。 WCFはコンソールでもホストできます。あなたは本当にリンゴとオレンジをここで比較しています。

関連する問題