reducing the memory consumption by wcf services - wcf

i have an asp.net and c# application using an wcf service and has been hosted in IIS
and now the memory consumption by the wcf service was increasing with time.
can any one guide me in making the wcf service to consume less space

When memory consumption rises, your service is probably leaking memory. Although a small memory rise is expected to happen during the first 100 or so calls of the web service, it should at one point stabilize around a specific usage with regular usage. You will have to check your service code for anything that could cause this leaking memory. (For example, don't rely too much on the automated garbage collection but assign null to variables that you won't use anymore to free them sooner.)

well for one thing, you can make the WCF service a per call instance. Which means it will create a service instance for each request, and then tear it down afterwards.

Related

Reuse WCF server instance between operations, without concurrency

How can I make the WCF server instance (the instance of the class in the .svc.cs / .svc.vb file) stay alive between requests?
It's a stateless, read-only type of service: I'm fine with different clients reusing the same instance. However, it's not thread-safe: I don't want two threads to execute a method on this instance concurrently.
Ideally, what I'm looking for is that WCF manages a "worker pool" of these instances. Say, 10. New request comes in: fetch an instance, handle the request. Request over, go back to the pool. Already 10 concurrent requests running? Pause the 11th until a new worker is free.
What I /don't/ want is per-client sessions. Startup for these instances is expensive, I don't want to do that every time a new client connects.
Another thing I don't want: dealing with this client-side. This is not the responsibility of the client, which should know nothing about the implementation of the server. And I can't always control that.
I'm getting a bit lost in unfamiliar terminology from the MSDN docs. I have a lot working, but this pool system I just can't seem to get right.
Do I have to create a static pool and manage it myself?
Thanks
PS: A source of confusion for me is that almost anything in this regard points toward the configuration of the bindings. Like basicHttp or wsHttp. But that doesn't sound right: this should be on a higher level, unrelated to the binding: this is about the worker managers. Or not?
In the event that you have a WCF service that centralizes business logic, provides/controls access to another “single” backend resource (e.g. data file, network socket) or otherwise contains some type of shared resource, then you most likely need to implement a singleton.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
In general, use a singleton object if it maps well to a natural singleton in the application domain. A singleton implies the singleton has some valuable state that you want to share across multiple clients. The problem is that when multiple clients connect to the singleton, they may all do so concurrently on multiple worker threads. The singleton must synchronize access to its state to avoid state corruption. This in turn means that only one client at a time can access the singleton. This may degrade responsiveness and availability to the point that the singleton is unusable as the system grows.
The singleton service is the ultimate shareable service, which has both pros(as indicated above) and cons (as implied in your question, you have to manage thread safety). When a service is configured as a singleton, all clients get connected to the same single well-known instance independently of each other, regardless of which endpoint of the service they connect to. The singleton service lives forever, and is only disposed of once the host shuts down. The singleton is created exactly once when the host is created.
https://msdn.microsoft.com/en-us/magazine/cc163590.aspx

How does WCF instance work

I am trying to understand how instances with WCF works. I have a WCF service which the InstanceContextMode set to PerCall (so for each call of every client a new instance will be created) and ConcurrencyMode set to Single (so the service instance is executing exactly one or no operation call at a time).
So with this I understand that when a client connects a new instance is created. But what happens when the client leaves the service. Does the instance die. The reason I ask is because I need to implement a ConcurrentQueue in the service. So a client will connect to the service and put loads of data to be processed and then leave the service. The workers will work of the queue. After the work is finished I need the instance to be destroyed.
Basically, learning from the "WCF Master Class" tought by Juval Lowy, per-call activation is the preferred choice for services that need to scale, i.e. that need to handle lots of concurrent requests.
Why?
With the per-call, each incoming request (up to a configurable limit) gets its own, fresh, isolated instance of the service class to handle the request. Instantiating a service class (a plain old .NET class) is not a big overhead - and the WCF runtime can easily manage 10, 20, 50 concurrently running service instances (if your server hardware can handle it). Since each request gets its own service instance, that instance just handles one thread at a time - and it's totally easy to program and maintain, no fussy locks and stuff needed to make it thread-safe.
Using a singleton service (InstanceContextMode=Single) is either a terrible bottleneck (if you have ConcurrencyMode=Single - then each request is serialized, handled one after another), or if you want decent performance, you need ConcurrencyMode=Multiple, but that means you have one instance of your service class handling multiple concurrent threads - and in that case, you as a programmer of that service class must make 100% sure that all your code, all your access to variables etc. is 100% thread-safe - and that's quite a task indeed! Only very few programmers really master this black art.
In my opinion, the overhead of creating service class instances in the per-call scenario is nothing compared to the requirements of creating a fully thread-safe implementation for a multi-threaded singleton WCF service class.
So in your concrete example with a central queue, I would:
create a simple WCF per-call service that gets called from your clients, and that only puts the message into the queue (in an appropriate fashion, e.g. possibly transforming the incoming data or something). This is a quick task, no big deal, no heavy processing of any kind - and thus your service class will be very easy, very straightforward, no big overhead to create those class instances at all
create a worker service (a Windows NT service or something) that then reads the queue and does the processing - this is basically totally independent of any WCF code - this is just doing dequeuing and processing
So what I'm saying is : try to separate the service call (that delivers the data) from having to build up a queue and do large and processing-intensive computation - split up the responsibilities: the WCF service should only receive the data and put it into a queue or database and then be done with it - and a second, separate process should do the processing/heavy-lifting. That keeps your WCF service lean'n'mean
Yes, per call means, you will have a new insance of the service per each connection, once you setup the instance context mode to percall and ConcurrencyMode to single, it will be single threaded per call. when the client leaves, done with the job, your instance will dispose. In this case, you want to becareful not to create your concurrentqueue multiple times, as far as i can imagine, you will need a single concurrentqueue? is that correct?
I would recommend you to use IntanceContextMode=Single and ConcurrencyMode to Mutli threaded. This scales better.if you use this scheme, you will have a single concurrent queue, and you can store all your items within that queue.
One small note, ConcurrentQueue, has a bug, you should be aware of, check the bug database.

WCF Service calling an external web service results in timeouts in heavy load environment

I have got the following scneario:
Our .NET client calls our WCF service - which in turn calls an external third party service to retrieve some data. Once the data is retrieved, our WCF service sets some values and then returns the control back to the client. The process of calling the external service has to be synchronous.
My problem is that this all works in a low load environment but when load gets high then we start queueing multiple requests, the WCF service starts timing out. We have set the "sendTimeout" property for the binding to 5 seconds and it times out after that.
I've tried replacing the external service with a mocked out local version and that handles the load OK but on the same hand the call to external service on it own is very quick - around 0.5 second. I can only presume that the timeouts are happening because too many requests were queued and WCF service couldn't respond within those allocated 5 seconds.
I have tried the following:
Set the values of maxConcurrentCalls, maxConcurrentSessions & maxConcurrentInstances to very high numbers
Set the value of system.net - connectionManagement - maxconnection to a very high number
Does any one have any ideas about what we can do in this scneario?
does your cpu peak during these high load times ? if not then you might be running out of threads. Make your wcf service that receives the original call asynchronous, and then call the external service asynchronously.
you will have to use asnyc pattern throughout your call chain to make sure nothing is blocking the thread.
http://msdn.microsoft.com/en-us/library/ms731177.aspx

Concurrent access to WCF client proxy

I'm currently playing around a little with WCF, during this I stepped on a question where I'm not sure if I'm on the right track.
Let's assume a simple setup that looks like this: client -> service1 -> service2.
The communication is tcp-based.
So where I'm not sure is, if it makes sense that the service1 caches the client proxy for service2. So I might get a multi-threaded access to that proxy, and I have to deal with it.
I'd like to take advantage of the tcp session to get better performance, but I'm not sure if this "architecture" is supported by WCF/network/whatever at all. The problem I see is that all the communication goes over the same channel, if I'm not using locks or another sync.
I guess the better idea is to cache the proxy in a threadstatic variable.
But before I do that, I wanted to confirm that it's really not a good idea to have only one proxy instance.
tia
Martin
If you don't know that you have a performance problem, then why worry about caching? You're opening yourself to the risk of improperly implementing multithreading code, and without any clear, measurable benefit.
Have you measured performance yet, or profiled the application to see where it's spending its time? If not, then when you do, you may well find that the overhead of multiple TCP sessions is not where your performance problems lie. You may wish you had the time to optimize some other part of your application, but you will have spent that time optimizing something that didn't need to be optimized.
I am already using such a structure. I have one service that collaborates with some other services and realise the implementation. Of course, in my case the client calls some one-way method of the first service. I am getting very good benifit. Of course, I also have configured it to limit the number of concurrent calls in some of the cases.
Yes, that architecture is supported by WCF. I deal with applications every day that use similar structures, using NetTCPBinding.
The biggest thing to worry about is the ConcurrencyMode of the various services involved, and making sure that they do not block unnecessarily. It is very easy to get into a scenario where you will be guaranteed timeouts, or at the least have poor performance due to multiple, synchronous calls across service boundaries. Even OneWay calls are not guaranteed to immediately return.
careful with threadstatic, .net changes the thread so the variable can get null.
For session...perhaps you could use session enabled calls:
http://msdn.microsoft.com/en-us/library/ms733040.aspx
But i would not recomend using if you do not have any performance issue. I would use the normal way, or if service 1 is just for forwarding you could use that functionality easily with 4.0:
http://www.sdn.nl/SDN/Artikelen/tabid/58/view/View/ArticleID/2979/Whats-New-in-WCF-40.aspx
Regards
Firstly, make sure you know about the behaviour of ThreadStatic in ASP.NET applications:
http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html
The same thread that started your request may not be the same thread that finishes it. Basically the only safe way of storing Thread local storage in ASP.NET applications is inside HttpContext. The next obvious approach would be to creat a wrapper client to manage your WCF client proxy and ensure each IO request is thread safe using locks.
Although my personal preference would be to use a pool of proxy clients. Whenever you need one pop it off the pool queue and when you're finished with it put it back on.

WCF Self Hosting Performance

I am in the process of writing an enterprise-level application utilizing WCF and NetTCP services. I chose NetTCP initially out of curiosity, but later determined it to be the best option for me since I can have services that are called that take 5+ hours to return results due to the amount of data crunching involved.
The way I currently spawn my services is a multi-step process. I have a configuration piece (using System.Configuration) that specifies some of the default stuff (port number, server name for clients connecting in, whether to enable HTTP as well as NetTCP, etc) and that has a collection of "services" underneath it. For example, here's what a basic one looks like:
<serverConfiguration tcpListenerPortNumber="60000" httpGetEnabled="true" httpListenerPortNumber="6000" serverName="localhost" retryEnabled="true" retryInterval="5" maxRetryAttempts="3">
<services>
<add virtualDirectory="Service1" applicationName="Service1" assembly="SampleService" type="SampleService.Service1" />
</services>
</serverConfiguration>
Basically what's happening here is my Windows service kicks off and looks at everything in the <services /> collection and spawns off a thread per service to speed startup time and each thread contains an AppDomain where the service truly lives so if a service has some kind of fault it doesn't bring the system down.
The "problem" I am running into is this application is hosting approximately 20 services and it takes a good 15-20 seconds for all the services to be up and running. I did the threading and AppDomain pieces to get it down to that value (used to take over a minute as each service was opened sequentially) but it still seems to me that this could actually go a lot faster.
Anyone have any suggestions? Google Bing has a plethora of examples for hosting one service but I'm not finding much out there for real-world applications (sadly "Hello World" just isn't appealing to end users). If you're currently hosting multiple services via a Windows Service and NetTCP, how are you doing it?
I figured it out finally and it had nothing to do with WCF or my configuration pieces after all. When I was creating the AppDomain I stole the code from another project we had that was much smaller in size and found that the section creating AppDomains was using the SingleDomain option. Changing it to MultiDomain made things go to >4 seconds for total load and memory usage dropped to ~40MB from ~150MB.
Thanks for the assistance though - at least it got me reviewing the code again!
I have three suggestions:
Firstly, if a call can take 5+ hours, I would consider a queuing / call back style architecture.
Consider splitting your services into 20 windows services, where each service runs in it's own windows services. This adds complexity and increases memory usage, but an individual service may be available faster.
Lastly, check the code that is in the consructor of the service, for any unneeded code.