WCF Restful service bad performance - c#

My wcf restful service manages to serve only 2 requests/sec!
detailed:
I've created a wcf restful service which exposes only one method via GET verb.
The method makes no logic, and returns immediately.
I've also created a test client in order to check the service throughput and performance, which makes requests by WebHttpRequest.
The service was able to process only 2 requests/sec!
I also made a request to the service through my browser, and the same result: 500ms for one request.
Then I changed the service binding to netTcpBinding and the service was able to process around 2000 requests/sec.
The service was running under a windows service, and hosted by WebServiceHost with WebHtppBinding.
good to mention that both client and the service was running in the same server.
Does it make any sense that wcf restful service has such poor performance?
Would Appreciate any help. Thanks.

No, it makes no sense and probably points to a problem with your testing. How was your REST test client written? Are you aware that, by default, .NET will only allow two open connections to any domain for a "regular" .NET process? It's increased to ten automatically for ASP.NET apps.
That information is documented here in ServicePointManager.DefaultConnectionLimit. You can increase this programatically or through config by adding a higher limit for the domain you're trying to connect to. Config wise this would look something like this:
<system.net>
<connectionManagement>
<add address="www.myserver.com" maxconnection="20" />
</connectionManagement>
</system.net>
You can open up connections for all domains using address="*" if that's your desire.
As for the delay you're seeing, it could be the result of other features that are on by default such as UseNagleAlgorithm or, if your POST'ing, Expect100Continue.

Related

Architecture for hosting WCF services for handling large no of concurrent request

I have windows service developed in .Net Framework 4.5. This process (windows service) is hosting 3 different soap based WCF services. Each WCF service is running on different port but inside the same process (windows service). Many of the clients are consuming these 3 soap based WCF services for different purpose. This communication happens through https protocol in LAN environment. Clients communicate periodically (say for instance after every 15 or 30 seconds) to these WCF services. We call it as heartbeat mechanism. For each call to any method in the service, some amount of processing takes place on service side. This mechanism works fine for few hundred clients i.e. about 200 to 300 clients. But as no of client’s increases, many clients starts experience delay. I understand that this architecture is not enough capable to handle large no of request. But to improve the performance of the system, I have thought of following ways
Isolation of the services for scalability and stability. One of the way is to host each WCF service into separate windows service. So there will be 3 different windows services each of it will have instance of WCF service. Deployment point of view this looks painful to me.
Instead of self-hosting, host it in IIS. I think then IIS will
manage the resources of service in optimized manner.
So question is
Whether isolation of services into different windows services on the same machine will really improve the performance or not? I do not want these services to be deployed on more than one machine for load balancing. Doing it so will increase the cost to the customer (due to hardware, windows server licensing cost etc.). Due to this customer will loose the features such as high availability but that is fine if he/she is not willing to spend more.
Whether IIS hosting will perform better than hosting in windows services?
Will this mechanism i.e. isolation of service will improve the stability of the system.
IIS hosting is the preferred method of hosting soap based wcf services, rule of thumb is to adhere to the following:
Ensure your service is decorated with:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]. Or which ever instancing mode suits your scenario.
Ensure that your client closes calls and disposes accordingly all the time you make the call.
you might want to consider using the async calls to your service. emphasized text

There was no endpoint listening at Error sometimes

I have hosted my WCF webs services into public server and consumed this service from the WPF application and this app is using around 2500 users for the Login purpose.Most of the time it is working fine. But in some case it gives the following error.
“Error : There was no endpoint listening at …….. that could accept
the message. This is often caused by an incorrect address or SOAP
action”
Any idea why this is happening sometimes. How can I solve this issue? Is it related to port was busy that time?
Thanks in Advance,
You may want to consider monitoring performance counters for your WCF service.
WCF has built-in performance counters that show system metrics associated with WCF Service throttling and security, in addition to the typical Windows counters (cpu, memory, etc.)
To enable performance counters, include <diagnostics performanceCounters="All"/>
in the <system.serviceModel> section of the WCF Service configuration file.
You can then add counters for “ServiceModel” at the Endpoint, Operation and/or Service level.
The following link provides additional information:
http://blogs.microsoft.co.il/idof/2011/08/11/wcf-scaling-check-your-counters/
Good luck.

Implementing a cache in a WCF Service

I have a WCF service that caches certain data and uses it to respond to web requests. To deal with this requirement, I made the service a Singleton (using InstanceContextMode.Single and ConcurrencyMode.Multiple (yes, it's threadsafe)).
I've tried to set the timeout of the service to its maximum using the following binding:
<binding name="WebHttpBinding" receiveTimeout="24.20:31:23.6470000">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" />
</security>
</binding>
My problem is that the service instance dies at unpredictable intervals, meaning the first web request to hit will cause the cache to get rebuilt (a very slow process).
Ideally, the cache would rebuild at a set time each day without having to get hit by a web request. I could set the app pool to recycle at a set time, but this still wouldn't resolve the issue of the service not getting instantiated until the first web request. I'd rather not have to make a little scheduled script that sends a request to the service, as that is kind of hacky.
Is there a better strategy for performing caching in a WCF service? What have others done here? Is there a best practice?
There is an MSDN article on Caching Support for WCF Web HTTP Services, an excerpt is quoted below:
The .NET Framework version 4 enables you to use the declarative caching mechanism already available in ASP.NET in your WCF Web HTTP services. This allows you to cache responses from your WCF Web HTTP service operations. When a user sends an HTTP GET to your service that is configured for caching, ASP.NET sends back the cached response and the service method is not called. When the cache expires, the next time a user sends an HTTP GET, your service method is called and the response is once again cached..........
You might also want to look at:
memcached
Windows AppFabric
NCache
Caching Solutions
WCF Caching Solution - Need Advice
Also look at this on Velocity from Microsoft
I have implemented caching at a higher layer inside the webservice.
This way you can decide when to invalidate the cache, and when to deserialize from disk.
To make sure the cache is built before the first webrequest, add some code to global.asax to generate the cache upon load of the web server.
This is much simpler than doing it the "right way"
[OperationContract]
public void GetLargeComplexData();
public GetLargeComplexData()
{
// deserialize last cached data from db or file
...
// Verify the deserialized cache is not invalid
...
// if cache is invalid rebuild
...
//return cached data
...
}
The receiveTimeout isn't going to affect what you're trying to do. You should use AppFabric to keep your service always running. That way, whenever you recycle, AppFabric will automatically warm up your service. Just make sure that your cache gets built when your service is instantiated, not when it's first accessed.
You can use IIS7 application warmup module
http://blogs.iis.net/thomad/archive/2009/10/14/now-available-the-iis-7-5-application-warm-up-module.aspx
An option you can use is to move the cache out of the WCF service and into a dedicated cache service such as Memcached or use Microsoft AppFabric Caching
This allows you to separate the storage of cached data from the WCF service so you have more freedom in your architecture of how the data is managed and accessed.

Should I use a web service or wcf service with various endpoints? (Web service calling another web service on same server?)

I’m currently working on a web service application project which will run in IIS7 on Windows Server 2008. The web services will be invoked from various clients, from outside the server but also from other components from within the same server. (Other web services and windows services)
My view is that the purpose of web services is to expose functionality so that external clients can invoke it. I really don’t see much sense in a web service invoking another web service on the same server or a windows service invoking a web service on the same server. Please correct me if I’m wrong?
I’ve started looking into WCF, but I’m quite confused.
Would it be more appropriate to do the following?
Instead of a web service project implement a WCF service.
Expose two endpoints:
1)One, which will be exposed using traditional web service binding which will be invoked from external clients.
2)Another endpoint so that internal services, (other web services or windows services) can invoke them, supposingly more effectively, surpassing a security layer as these are aplications already running on the server.
Would my approach be correct or am I overcomplicating things?
Any suggestions or links which could point me in the right direction appreciated.
Thanks
A web service calling another web service?
If they have different responsibilities I think it's a good idea to separate them. You get better separation on concerns (easier to share with other projects / code bases), easier maintainability and independent deployability.
I would go with WCF and have two different endpoints for the different consumers, and for example use net.pipe for communication on the same server (if the client supports it) and http for external clients.
I think WCF gives you more power and flexibility that old xml web services, and the configuration part is really good.
BasicHttpBinding will give you most interoperability with external clients.
named pipes will give you the best efficiency when both services are hosted on same machine.
BasicHttpBinding is like old asmx & XML web services.
Exposing both endpoints is AOK!
One service calling another service is NOT unusual.
Hosting multiple services on same machine is common. In the enterprise, running multiple instances of SQL-Server is commonplace. Of course it depends on hardware, services & response times.

Starting self hosted WCF services on demand

Is it possible to start self hosted WCF services on demand?
I see two options to accomplish this:
Insert a listener in the self hosted WCF's web server and spin up a service host when a request for a specific service comes in, before WCF starts looking for the existence of that endpoint; or
Integrate a web service in process, start a service host for a request if it isn't running yet and redirect the request to that service host (like I suspect IIS does).
I cannot use IIS or WAS because the web services need to run in process with the UI business logic.
Which is feasible and how can I accomplish this?
EDIT:
I cannot just start the service hosts because there are hundreds, most (about 95%) of which are (almost) never used but need to be available. This is for exposing a business logic layer of 900 entities.
You could do a locator service setup. Basically always expose a lightweight service that returns the address of the 'actual' services. Every time the address of a particular service is requested, go ahead and spin it up.
If you're worried about cleaning it up, you could keep a list of the service hosts and wire in some sort of inactivity timeout so you could periodically shut down the service hosts.
There are some design concerns here - the concept of "calling one service before you call another one" is probably considered a bad idea on some level (sounds like coupling the state of two services).
Went the following route:
Create a single service host;
Create a dynamic proxy which implements all service interfaces;
Add a service endpoint for every interface the dynamic proxy implements;
Dispatch to the correct implementation from the dynamic proxy.

Categories