Note: Cross posted from Sajay.
We generally need to have a quick set of performance counters to identify a performance issue with a service. Shown below are three new counters that you will find with WCF 4.0. I also want to emphasize on the Calls outstanding counter here since this is one very useful and is indicative of calls getting queued up.
PercentOfMaxCalls
Reports # of active requests as % of max calls
Reports the numbers of messages being processed + in the wait queue as a percentage of MaxConcurrentCalls throttle
PercentOfMaxSessions
Reports # of active requests as % of max sessions
Reports the numbers of active instances + calls in the wait queue waiting for an instance as a percentage of MaxConcurrentInstances throttle
PercentOfMaxInstances
Reports # of active requests as % of max instances
Reports the numbers of messages in the wait queue due to MaxConcurrentSessions throttle
CallsOutstanding ( from 3.0)
Reports the # of calls waiting to be completed
Reports the number of in-progress calls to this service.
Here you see that the %Instance throttle has maxed out. What do you think we should do? You can guess what throttle we are hitting here.
Some common questions when trouble shooting performance problems:
% of MaxConcurrentCalls gives you an indication of how much closer you are to hitting your max throttle value. This means that if you have a max concurrent call of 10 and you have 10 outstanding calls then you have utilized 100% of your throttle and there is no more work that your service can do. So if you see that your % maxConcurrentCalls is very high it probably indicates you have a very low throttle value. Remember the default is 16 till v3.5 and 16* proc count for v4.0. Before 4.0 you needed to work this out by checking the calls outstanding throttle and your web.config to figure out this value. These new % performance counters would help you identify if you are hitting the max values from now.
We have bumped up the default number of sessions for service throttling behavior to 100 per CPU. But then again if you are seeing that %MaxConcurrentSessions is very high this means that you have exhausted all your session. This is probably because your clients are not closing either proxies and terminating sessions when you have less clients or possibly due to a very small MaxConcurrentSessions configuration.
This was one was interesting as the service was exposed as a fully typed service, but the client wanted to modify some parts of the xml. Ideally you can plug into any part to perform these operations, but the general requirement here was that they needed a simple pointer to the Body and didn't care much about anything else.
For example you can get the XElement from the body using a simple operation and use the Message object on the client to get a pointer to the body.
[ServiceContract(Namespace="http://www.sajay.com/")] public interface IClientProxy { [OperationContract(Action="http://www.sajay.com/getdata", ReplyAction="http://www.sajay.com/getdataresponse")] Message DoWork(); } IClientProxy proxy = cf.CreateChannel(); Message msg = proxy.DoWork(); XNode node = XElement.ReadFrom(msg.GetReaderAtBodyContents());
[/code]
So the service can return a typed object, but the client doesn't have to handle the message in the same way. Understanding the Message class here helps you appreciate how the serializer and encoder is decoupled from the message representation. Basically WCF does not constrain the native format of your message on either the producer's or the consumer's side. It merely conforms to some rules of invoking a set of abstract classes classes which you wire up by virtue of specifying the encoder and the serializer. The fact that we have XML semantics around with abstract classes like the XmlReader/XmlDictionaryWriter etc doesn't actually mean that WCF converts everything to XML before it can process the message. It merely uses these to invoke the required parts to obtain things like the header/body and other properties. The Message however can be represented natively in any form like binary/json/atom/ or any whacky type as long as you wire them up properly and can retrieve them in some manner.
This should give you some insight into how much more powerful the message model is compared to simple RPC style contracts. http://msdn.microsoft.com/en-us/library/ms734675.aspx With 4.0 and workflow services, you will see this becoming more and more the default way of thinking about messages and services.