In WCF, whats the difference between the binding setting maxConnections and the ServiceBehaviors serviceThrottling settings (maxConcurrentCalls,maxConcurrentInstances,maxConcurrentSessions)?
I'm trying to get my WCF service setup and I'm not exactly sure how those work with each other to limit connections.
Two things are important to consider:
the serviceThrottling behavior is a service-/server-side setting that determines how many concurrent calls, instances and sessions are supported by the server. This is independent of any binding or service endpoint - it's a service-wide setting. This allows you to tweak how many concurrent requests (and/or sessions) a specific service can handle - that depends on things like server "power", RAM, CPU and a lot more factors. Those values are kept fairly low by default, to avoid servers from being "overloaded" and thus rendered unresponsive by large floods of requests (erroneously or maliciously)
the maxConnections setting on the binding is specific to the netTcpBinding (and it's "cousins", like the netNamedPipe and various Azure-oriented net***Relay bindings) and has to do with connection pooling. Much like ADO.NET database connections are pooled, TCP/IP connections to the server can be pooled and reused to reduce the overhead of having to destroy and re-create them. This is mostly a client-side setting (although it also has effects on the server-side), and again: it's specific to the netTcpBinding (and cousins; all based on TCP/IP) and doesn't exist for any of the other bindings.
See: More details on MaxConnections for more, great in-depth insights into the ins and outs of this setting.
Related
I have a question with regards to WCF client channel lifetime while using Message security, but first, a few notes on my company's setup and guidelines:
Our client-server applications are solely for intranet use
Our clients are WPF applications
Our company's guidelines for WCF usage are:
Use wsHttpBinding
Use Message Security
Service InstanceMode: PerCall
Service ConcurrencyMode: Multiple
It is the first time I have to use message security on an intranet setup. Here's how I typically use my client channels to limit the amount of resources kept on the client and server and literally just to keep things simple:
Instantiate + open channel (with ChannelFactory)
Make the WCF call
Close / dispose the channel asap
While monitoring this strategy with Fiddler 2, I noticed that because of Message Security, a single WCF call ended up causing 5 round-trips to my service:
3 initial round-trips for handshaking
1 round-trip for the actual WCF call
1 call to close the session (since I am using PerCall, I am assuming this is more a security session at the IIS level)
If I were to turn off Message Security, as one would expect, one WCF ended up being... A single round-trip.
As of now, I must use Message Security because that's our guideline. With this in mind and knowing that we make hundreds of WCF calls from each client WPF app a session, would you therefore advise to open the client channel and keep it open for re-use instead of disposing of it every time?
I would advise not to preemptively turn off features until you know they are a known problem. Preoptimization is needless work. Until you notice your clients having lagging problems, I would not worry about the message security. At that point, try a few things: one of your approaches of keeping a client open longer; two, try grouping requests together without turning off message security; three, consider caching, if you can; four, if the message security is the final culprit, then try a different method. I wouldn't just turn something off because I see a bit more network traffic until I knew it was the absolute last thing that I could do to improve performance.
We are getting the following error in the WCF tracelog.
The system hit the limit set for throttle 'MaxConcurrentSessions'. Limit for this throttle was set to 10. Throttle value can be changed by modifying attribute 'maxConcurrentSessions' in serviceThrottle element or by modifying 'MaxConcurrentSessions' property on behavior ServiceThrottlingBehavior
We couldn't find a good answer to modify the "MaxConcurrentSessions" attribute without using a custom binding on the WCF adapter.
looked at the following article but don't want to change the existing binding
http://msdn.microsoft.com/en-us/library/dd203050%28v=bts.10%29.aspx
One more point: working for a while, as we get the load, then everything locks up
Thanks,
Krishna.
You don't mention which binding you are using, but am guessing that it is WCF-wsHttpBinding (basicHttpBinding doesn't support Sessions AFAIK).
I would suggest that you do switch to WCF-Custom, as it has more configuration options. Simply choose the binding type as wsHttBinding and it will work the same as the WCF-wsHttpBinding (we've configured all of our basic and wsHttp receive locations with Wcf Custom without any issues, FWIW)
You need to manually add the serviceThrottling behaviour on the behaviours tab of your receive location. From MSDN
Before any elements of the ServiceThrottlingBehavior service
behavior can be modified, you must first add the serviceThrottling
behavior extension to the Behaviors tab of the WCF-Custom* Transport
Properties dialog box. To add serviceThrottling to the list of
Behaviors, select the Behaviors tab of the WCF-Custom* Transport
Properties dialog box, right-click ServiceBehavior under Behavior,
click Add extension, select serviceThrottling, and then click OK. Then
click to select the properties available under
ServiceThrottlingElement and change the value for the properties as
needed.
It is likely that you will also need to simultaneously increase the maxConcurrentCalls and maxConcurrentInstances as well.
The default recommendation in .NET 4 is at least 16*Cores, although the above link recommends >= 200 for maxConcurrentCalls.
That said, you may find BizTalk host throttling kicking in after a sustained period of heavy incoming load, which could cause the perceived lockup that you've described. Use WMI or perfmon counters to check the publishing and delivery throttling states of your hosts, and if this is the case, you will need to start the long haul in tuning your servers, hosts and orchestrations to avoid / limit the impact of throttling. BTS host throttling is fatal to synchronous receives like WCF, since response messages can be significantly delayed, causing the clients to timeout, and will also then cause the responses to be suspended once BTS does get around to processing them.
I'm building web application (in this context the client) which talk with a different process (in this context the server) through a namedpipe wcf service (WCF 4).
After reading many articles I was thinking to create a pool of proxy connected to the server (I've read it provide better performance) used in roundrobin.
Each call will be very short, on the server i need to reads and writes simple properties on few objects but this objects are shared so i must use locks in any case.
I expect very high concurrency.
Beacuse of the pool, the client will have N session always open with server.
I was wondering what should be the best settings for InstanceContext-ConcurrencyMode between PerSession-Single or SingleInstance-Multiple.
Thank You
My opinion: Do not use custom pool of proxies. Use build-in pooling of connections. You can't fully control connectionPooling in predefined bindings but you have full control in customBinding when using namedPipeTransport.
From implementation perspective in your client - use new proxy for each client's request. Don't share proxies among requests.
I am designing a WCF service.
I am using netTCP binding.
The Service could be called from multi-threaded clients.
The multi-threaded clients are not sharing the proxy.
1. WCF Service design question.
Client has to sent these 2 values in every call: UserID and SourceSystemID. This will help the Service to identify the user and the system he belongs.
Instead of passing these 2 values in every call, I decided to have them cached with the Service for the duration of call from the client.
I decided to have a parameterized constructor for the Service and store these values in the ChannelContext as explained in this article.
http://www.danrigsby.com/blog/index.php/2008/09/21/using-icontextchannel-extensions-to-store-custom-data/
Initially I wanted to go with storing the values in the Session and have a method for initialization and termination. But there I found that I need to manually clean up the session in each case. When I am storing values in the channel context, I don’t have to clean it up every time and when the channel closes the values stored are already destroyed.
Can somebody please make sure that I am correct in my assumption?
2. Should I use SessionMode?
For my contract, I used : [ServiceContract(SessionMode = SessionMode.Required)] and without this service attribute.
Irrespective of my choice, I am always finding a value for : System.ServiceModel.OperationContext.Current.SessionId
How can this be explained?
When I say SessionMode.Required, does my InstanceContextMode automatically change to PerSession?
3. InstanceContextMode to be used?
My service is stateless except that I am storing some values in the Channel Context as mentioned in (1).
Should I use Percall or PerSession as InstanceContextMode?
The netTcp always has a transport-level session going - so that's why you always have a SessionId. So basically, no matter what you choose, with netTcp, you've got a session-ful connection right from the transport level on up.
As for InstanceContextMode - as long as you don't need anything else from a session except the SessionId - no reliable messaging etc. - then I'd typically pick Per-Call - it's more scalable, it typically performs better, it gives you less "glue" to worry about and less bits and pieces that you need to manage.
I would use an explicitly required session only if you need to turn on reliable messaging or something else that absolutely requires a WCF session. If you don't - then it's just unnecessary overhead, in my opinion.
Setting SessionMode to SessionMode.Required will enforce using bindings which support sessions, like NetTcpBinding, WSHttpBinding, etc. In fact if you try using a non-session-enabled binding , the runtime will throw an exception when you try to open the host.
Setting InstanceContextMode to PerSession means that only one instance of the service will be crated per session and that instance will serve all the requests coming from that session.
Having SessionId set by the runtime means that you might have a transport session or a reliable session or security session. Having those does not necessarily mean you have an application session , that is a single service object serving the requests per proxy. In other words, you might switch off application session by setting InstanceContextMode=PerCall forcing the creation of a new service object for every call, while maintaining a transport session due to using netTcpBinding, or a reliable or security session.
Think of the application session that is configured by InstanceContextMode and Session Mode as a higher level session, relying on a lower-level session /security, transport or reliable/. An application session cannot actually be established without having one of the other sessions in place, from there the requirement for the binding .
It is getting a bit long already, but for simple values I would recommend you to pass those values every time instead of creating application session. That will ensure the service objects have a short lifetime and no unnecessary resources will be kept alive on the server. It makes a lot sense with more clients, or proxies talking to your service. And you could always cache the values in the clients, even pass them as custom headers if you want.
Does anyone have any experience with how well web services build with Microsoft's WCF will scale to a large number of users?
The level I'm thinking of is in the region of 1000+ client users connecting to a collection of WCF services providing the business logic for our application, and these talking to a database - similar to a traditional 3-tier architecture.
Are there any particular gotchas that have slowed down performance, or any design lessons learnt that have enabled this level of scalability?
To ensure your WCF application can scale to the desired level I think you might need to tweak your thinking about the stats your services have to meet.
You mention servicing "1000+ client users" but to gauge if your services can perform at that level you'll also need to have some estimated usage figures, which will help you calculate some simpler stats such as the number of requests per second your app needs to handle.
Having just finished working on a WCF project we managed to get 400 requests per second on our test hardware, which combined with our expected usage pattern of each user making 300 requests a day indicated we could handle an average of 100,000 users a day (assuming a flat usage graph across the day).
In addition, since it's fairly common to make the WCF service code stateless, it's pretty easy to scale out the actual WCF code by adding additional boxes, which means the overall performance of your system is much more likely to be limited by your business logic and persistence layer than it is by WCF.
WCF configuration default limits, concurrency and scalability
Probably the 4 biggest things you can start looking at first (besides just having good service code) are items related to:
Bindings - some binding and they protocols they run on are just faster than others, tcp is going to be faster than any of the http bindings
Instance Mode - this determines how your classes are allocated against the session callers
One & Two Way Operations - if a response isn't needed back to the client, then do one-way
Throttling - Max Sessions / Concurant Calls and Instances
They did design WCF to be secure by default so the defaults are very limiting.