2014년 3월 5일 수요일

WCF Performance 올리기

WCF Service의 경우 다양한 Binding과 수많은 옵션들로 인해 Performance가
천차만별이다.

특히 개발단계에서 보면 예상하지 못한 낮은 Performance로
고생하는 경우들이 많다.

아래 글은 특히 netTcpBinding을 사용하는 경우
Performance를 향상시킬 수 있는 방법,
그리고 종종 실수하게 되는 Debug모드와 Release모드간의
극단적인 Performance차이에 대해 설명하고 있다.


http://blog.shutupandcode.net/?p=1085

추가로 "IT Expert, 유수석의 WCF 바이블"(유경상)이란 책을 읽어보면 좋을 듯 하다.
책값이 비싸지만 괜찮은 책이라는 이야기를 많이 들었다.
아니면 과천도립도서관에서 대출받는 것도 방법...
근데 없으면? <해당 사이트가 사라진 듯 하여 저장된 페이지 추가>

High Performance WCF Services : netTcpBinding

By Terrance A. Snyder On April 12, 2010 · 15 Comments · In .NET
A bit of a divergence away from Azure today. I had two questions I wanted to answer before running comparison of performance in Azure.

I received some requests for some down-loadable source. It can be downloaded here: NetTcpBindingExample

How fast can WCF go? How about ~29,000 requests per second?

Ah, the eternal question… The benefit of finding the answer is that it puts some sanity checks in place whenever we are planning our architecture. If a business user wants to have two million transactions processed in a minute can you do this with WCF? What about 1 hour? What about 24 hours? Somewhere in there is a “yes we can do this”, but alas, unless you read on you wont know where to start…

Further if you don’t know the absolute fastest WCF can perform how do you know if you are running ‘slow’ or ‘good’. What about how many servers you may need? Baselines are great tools… read on…

WCF Binding Comparisons

Below charts show the comparison of basicHttpBinding, binaryHttpBinding, and netTcpBinding.

One Way Operations with Basic String (Calls Made Per Second)
Compare2

Large Object Operation with Complex Object (Calls Made Per Second)
Compare

By far the best channel is netTcpBinding for performance – both for large objects and one-way operations. You’ll note the benefit of binaryHttpBinding over basicHttpBinding is not apparent when dealing with small objects. This makes sense considering the network savings aren’t in play for our simple string operation.

The Service Tested

To answer “the fastest” question and to do sanity checks the below was the service interface created.

view sourceprint?
01.[ServiceBehavior(
02.    ConcurrencyMode=ConcurrencyMode.Multiple,
03.    InstanceContextMode=InstanceContextMode.Single,
04.    AddressFilterMode=AddressFilterMode.Any)]
05.public class HelloWorldService : IHelloWorldService
06.{
07.    public void MockOneWayOperation(string name)
08.    {
09.          // do absolutely nothing
10.    }
11. 
12.    public CompositeType MockTwoWayOperation(CompositeType composite)
13.    {
14.        return composite;
15.    }
16.}
You will note that this service does absolutely nothing. We took out database calls, or any other dependency… Its the simplest and most pure service ever… you can’t make a faster service so it’s good in that it eliminates any external dependency (save network).

It is recommended that you always call Channel.Open()

On top of just the binding chosen you have one more thing to worry about (well two to be exact). If you are calling a WCF service please be sure to call yourclient.open(); explicitly before actually calling a service operation.

Calling svc.Open() on netTcpBinding helps, please do it… your mom will thank you
netTcpBinding_Small

Calling svc.Open() on WCF BasicHttpBinding helps a lot as you can see below
BasicHttpBinding_Small

Configuration of net.tcp when running in port sharing mode:
http://msdn.microsoft.com/en-us/library/aa702669.aspx

Note: When running your WCF services in netTcpBinding using port sharing the configuration of the netTcpBinding is ignored. You must change these settings as described in the above MSDN document to get maximum throughput.

My performance isn’t that good?! What voodoo are you using?!

Please be sure when running your tests you answer NO to both these questions:

Is your web.config in debug mode?
Is your test client running in debug?

Running with any of the above is a recipe for disappointment. As an example of how much of a disappointment you are in for, the below chart shows the potential performance hit you will take if you have either the server or the client in debug (or both).

Keep in mind this is the same high performance netTcpBinding!

The only thing I am doing here is running the service in debug and the client tester (VS Unit Test) in debug.

Note the extreme difference in performance when client is running in debug
debug

When measuring performance please be sure your WCF service is not running in debug (web.config) and your client is not running in debug. If you are using a Visual Studio Unit Test for quick performance evaluation be sure to run the unit test as “Run Selection”, not “Debug Selection”.

Measurements

table

As you can see the running debug+debug without server GC on the fastest WCF binding will cause you to be running 29x slower than you would otherwise expect.

Maximum Performance WCF netTcpBinding Configuration…

No security, no reliable sessions, max serialization, max listen backlog.

view sourceprint?
01.
02.  
03.    
04.      
08.    
09.  
10.  
11.    
12.      
20.        
21.          
22.          
23.        
24.        
25.      
26.    
27.  
28.  
29.    
30.      
31.        
32.        
33.      
34.    
35.  
36.
37.
38.  
39.
40.
41.  
42.
 
If you enjoyed this article, please consider sharing it!
15 Responses to High Performance WCF Services : netTcpBinding

Alik Levin says:
April 12, 2010 at 12:56 pm
very nice! i love the flow and the details. it goes to my personal KB under WCF/Perf ;)

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Thanks! Feedback is always appreciated.

Reply
Tweets that mention Terrance A. Snyder -- Topsy.com says:
April 12, 2010 at 6:05 pm
[...] This post was mentioned on Twitter by Solidsoft. Solidsoft said: Terrance A. Snyder: It is important to note that when running your wcf services in net.tcp you're configuratio… http://bit.ly/b4vTq0 #WCF [...]

Reply
James Wilson says:
September 1, 2010 at 8:59 am
Excellent article! Your conclusions are well documented and the article is very down-to-earth and easy to understand. Well done.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Thank you.

Reply
Tom Boring says:
September 1, 2010 at 9:25 am
Great article! Jim (Wilson) had always told us (the folk he USED to work with) how fast netTCP was, but he never proved it. Of course, we trusted him…but then he left to work for some other company.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Sorry to hear about the loss of a valuable member. Always come prepared to back things up with metrics and for management types always show the classic bar chart of performance. Reduce the decision down to one slide and make it obvious what to do.

Reply
k9 says:
December 15, 2010 at 1:38 pm
nice article , I try to use the same netTcpBinding “ultra” for the client side proxy configuration and I had some errors relates to out of memory issues .

Reply
Valeriano Cossu says:
December 26, 2010 at 4:36 am
Very clear, I am going to use it.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:44 pm
Good to hear, make sure you check out the codeplex P&P book http://wcfsecurityguide.codeplex.com/

Reply
Konstantin says:
January 20, 2011 at 3:42 am
Hi, Terrance!
I wonder, what was the hardware you used to perform that benchmarks?

Did you used a gigabit network between client and server? How many CPU codes were in the server?

Thanks in advance.

Reply
Terrance A. Snyder says:
February 14, 2011 at 8:34 am
A simple Dual-core LGA995. Windows 2003 Server. Tests were run locally so client and server were running on same to remove network from equation. This was merely a test for “the fastest possible” on a CPU side. Of course smaller objects being transmitted would also mean that the binary would also be more efficient.

Thats the great thing about WCF, you can have both on at the same time (at least in Windows 2003 R2) so for internal communications use binary and external using SOAP/XML.

Reply
Gustavo says:
April 12, 2011 at 7:58 am
Hi Terrance, this is an interesting article. However I have a question, in the test you seem to be reusing the client in all the requests, and in real life, I would be creating a new client everytime I need to call the service. Do you know how creating a new client per request would impact the performance/numbers?
Thanks

Reply
Adactus - Official Blog | PERFORMANCE TUNING WCF says:
December 14, 2011 at 6:26 pm
[...] excellent article on WCF performance, from Terrance A. Snyder, shows the performance of various binding options in [...]

Reply
Maxim says:
January 1, 2012 at 10:15 am
Hi,

Great article!

About the .Open() – Do you mean to call it on the ChannelFactory or on the Client proxy?

Do you have an idea what the .Open() method does?

Reply