I have a desktop app that uploads 10 jpegs of size 2000 bytes in 1 second via my web service which is hosted under IIS
The Operation Contract is 1 way (ie not duplex) and I use MTOM in the binding.
Will there be any performance gain if I self-hosted it instead under a Windows Service?
There is a question with a interesting analyse about using different bindings for streaming data:
Streaming with WCF and MTOM
You may get improved response times because the ServiceHost will already be loaded into memory and ready to receive calls. This is not true of IIS hosting which may unload the appdomain during times of low traffic. So when a call does come in IIS will need to fire up the ServiceHost before it can process your call.
However, IIS provides you with some useful features such as reliability - a windows service can just crash and remain down for as long as it takes someone to notice.
Related
In order to improve performance* of a WCF service, one of the following can be done:
Use WCF inbuilt features (throttling etc)
Install multiple instances (separate websites in IIS) of the same service in the same machine.
I understand that these things are better tested than discussed but just wanted to get an opinion if someone has already tried both these approaches.
This service uses InstanceMode.PerSession and ConcurrencyMode.Multiple
Performance: This service handles data (MTOM encoded). There should not be any timeouts since clients will make synchronous calls to this service.
No, multiple endpoints from a single service won't help, as you describe it.
Yes, you can have a running WCF in IIS with multiple endpoints, but the same service is processing the requests whether they come into endpoints 1, 2, 3 or n. And since WCF requests are processed on their own threads, there's no benefit to adding extra end points.
Think of it this way: 10 requests come into a WCF service. Each request is processed on its own thread whether there are 10 endpoints or just 1. So there's no speed advantage gained by adding endpoints.
I've spent 2 years building industrial-scale WCF services. If you're worried about performance, the WCF service is the least of your worries. I've load tested a WCF service, sending 1000 concurrent users (each uploading multiple 157kb files) at a medium size (4 core) server; the server barely breaks a sweat while uploading 160 files/second.
If you're planning to build huge web service, the way to spread out the processing load is to have 1-n WCF web services fronted by a load balancer like F5. Then you can scale up to Amazon.Com size if you like.
I have already asked a similar question here: WCF Service calling an external web service results in timeouts in heavy load environment but I've got a better idea now as to what's happening so posting a new question.
This is what is happening:
.NET client sends multiple requests at the same time to a WCF service (if it helps - I'm replicating this scneario by using Visual Studio Load Tests)
The client has got a "sendTimeout" set to 5 seconds
The WCF service receives it and start processing it. The processing involves sending a request to an external service which could take about 1 second to come back with a response
This is where I think the problem is: the client has sent many requests to the service and since the service is still busy processing the concurrent requests, some of the reqeusts from the client are timing out after 5 seconds
I have tried the following:
Changed the InstanceContextMode to PerCall
Increased the values of maxConcurrentCalls & maxConcurrentInstances
Increased the value of connectionManagement.maxconnection in machine.config
But none of that seems to be making any difference. Does anyone has any idea how can I ensure that I don't run into this timeout issue?
OK, you say WCF and that is not enough. What binding are you using and where are you hosting it? If you are using IIS, the could be different underlying problem than self-hosting.
The likely reason is the small number of ThreadPool size. You can use ThreadPool.SetMaxThreads() to change this but beware this is a sensitive value. Have a look here.
Check out the following link:
http://weblogs.asp.net/paolopia/archive/2008/03/23/wcf-configuration-default-limits-concurrency-and-scalability.aspx
I'm not sure what you're trying to achieve. Since the WCF service is doing a time consuming operation, you can't overload it and expect it to function. You can do the following (check the link about to set the following):
Increase the receiving capacity of the wcf service
Increase the send timeout of the service
Increase the send timeout of the client
Increase the receive timeout of the client
Limit the outgoing connections to the wcf service
The best and most robust option would be to configure and use MSMQ with the WCF service.
In my application I need to push notifications of real time events from server to clients. The amount of data to pass is very small, mostly and Id. The number of clients listening simultaneously can be around 100 and I may have to publish one notification every 2 - 3 seconds. Both the server and client are built using .Net and WCF.
Given these requirements I have built a set of WCF services which will be run on a load balanced server cluster. The Instance context mode is Per Call and there is no need for sessions etc.
I am currently using BasicHttpBinding. Will TCP binding be better? Does it run on IIS 5 or 6? If not why?
What configuration for serialization can work best?
What are the things I need to do to make sure I get maximum performance?
Edit - Adding more information based on some of the responses -
I host a small WCF service in the client process using manual hosting. The server just calls this service on each client to push the data to all of them.
Firstly have you considered using messaging for what you are trying to achieve?
In answer to will TCP binding work better than BasicHttpBinding- almost certainly yes. If you want to use TCP, you can't use IIS- look into WAS with Windows Server 2008. If you're stuck with Windows Server 2003, then you'll have to host in a windows service instead.
You've made a good choice by choosing per call- this is the preferred instance management mode for creating scalable WCF services.
Edit:
Now you've update your question, I recommend you take a look at IDesign's Pub/Sub framework if you want to stick with WCF. I'd also look at Pub/Sub with MSMQ in WCF and also with "Vanilla" products such as Tibco RV.
If you need pushing data from service to clients you need sessions and you need duplex binding - NetTcpBinding or WSDualHttpBinding. It will not work with BasicHttpBinding because it allows only pulling data (client pools the service for changes). Push data means tha service sends data to clients when needed.
NetTcpBinding always crete session. It can't be hosted in IIS 6 or older. NetTcpBinding is allowed only in Windows Activation Service (WAS) which is extension of IIS 7.x. For older systems you need self hosting = windows service.
Edit:
Based on your description you need Publish-Subscribe message exchange pattern.
I'm developing a web application that needs to perform a task that consumes a lot CPU and Memory, and that also may last several minutes. In order to get a better user experience, I also developed a windows service that hosts a WCF service that performs this "high cost" task and that comunicates with the web app using msmq (message queues).
This worked great until I tried to make a load test... The windows service starts consuming a lot of resource, puttin the CPU to work at 100% and more than 1GB of memory. I've looked for optimizations and I've done a lot of tweaks to the code and I think that it is very efficient, but the task just requires a lot of resources.
The problem is that while the WCF service is working, the CPU gets used at 100% and the web app turns INCREDIBLY SLOW! I don't mind if the task that the WCF service does takes a couple of minutes more, but I want the web app to perform well for users.
So I'm wondering if there is a way to limit the resources that the WCF service can consume, giving priority to the web app.
Thanks in advance.
Juan
The easy solution would be to place the WCF service on a different machine.
The fact that the service is using alot of CPU is probably not related to you using WCF.
There are some ways that you may be able to improve the performance of your web app:
Process only one message at a time.
Break the jobs into smaller parts.
Set priority of the windows service to below normal in the task manager
Install more RAM on the server
I guess this is a problem of your Windows service design. When you decide to host WCF in Windows service you have to control resource utilization = you have to control throttling. You have to create configurable control over internal service processing so that you can change the load based on available resources. If you host WCF in IIS it already provides such control on AppPool level.
There are some freeware tools which allow limiting CPU usage for given process but that is not something I would recommend for production usage.
Best regards, Ladislav
We have an existing WCF service that makes use of wsDualHttpBinding to enable callbacks to the client. I am considering moving it to netTcpBinding for better performance, but I'm quite wary of moving away from the IIS-hosted service (a "comfort zone" we currently enjoy) into having our own Windows service to host it. I was hoping we could still host this on IIS 7 but Win2K8 won't be reality for us for some time.
What things should I watch out for when creating our own Windows service to host our WCF service? Things like lifetime management and request throttling are features that come free with IIS hosting so I'd also like to know how we can effectively host our service on our own without the convenience of having IIS do the hard work for us. Thanks! :)
So as you cannot host using WAS there are a couple of things to realise.
If the service crashes it doesn't restart by default (although you can change this in service properties)
IIS will recycle the application pool if it hangs or grows too big; you must do this yourself if you want the same sort of reliability.
You must create an account for the service to run under, or use one of the default services. Resit the temptation to run the service as SYSTEM or under an administrator account; if you want to use a built in account use NETWORK SERVICE.
It becomes harder to debug in situ.
Consider using a error logger such as log4net
Having said that I deployed a WCF/Windows service combination for a customer 9 months ago; it's heavily used and hasn't died once.
You can request throttle in a Windows service, it's part of the WCF configuration. Note the defaults are very low, it is likely you will have to increase these.
Hosting in a Windows Service Application (http://msdn.microsoft.com/en-us/library/ms734781.aspx) is a good start.
If you can host your service on Vista, you can also benefit from Windows Process Activation Service (WAS). WAS is a generalization of the IIS process activation, which can be used to activate processes over non-HTTP endpoints (TCP, Named Pipe, MSMQ). To learn more about WCF hosted in WAS, read http://msdn.microsoft.com/en-us/library/ms733109.aspx. To learn how to install and configure WAS, read http://msdn.microsoft.com/en-us/library/ms731053.aspx.