Currently working on a .NET solution for an application server. I'm using .NET 4.0 running on Windows Server 2008 R2 with IIS 7.5.
My requirements are:
The application server can run multiple Console applications at once on a schedule - Quartz.net looks like a really good solution to this problem - and is working well for me so far
The application server will also host a web application that will report on jobs (what time they ran, what they did, how long they took etc)
I would like to be able to restart the "service" that is running my jobs and trigger ad hoc jobs from the web interface.
The Service that is running my jobs needs to run all the time
Once this is live I will not have direct access to the machine to restart a Windows Service, but i could potentially setup IIS to be able to do this for me.
WCF Services looks quite promising to me - but I'm not sure where to host it. My current project uses a WCF Service to run console applications using the Quartz.net plugin. Configuration for what to run and when to run it is stored in an oracle database and my WCF service connets directly to the database to retrieve this information (not sure if that is the intended use of WCF).
If I host the WCF Service in IIS / WAS then running the console applications might be a security concern from what I've read. I can keep the WCF service running all the time using appFabric at least. Alternatively I could host it in a Windows Service and allow my web app to consume the WCF service to report on the jobs. I'm concerned about using a Windows Service though as I wont have direct maintenance access to this machine and if it breaks I'm in trouble. I would really like to be able to do the maintenance from a web application. A windows service also feel a little unnecessary given it can be hosted from IIS.
So my question is - is a WCF Service the right approach to this problem or can anyone think of a better approach?
If a WCF service is a good approach - where should I host it so that I can perform maintenance via a web interface given I will not have direct access to the machine itself?
Should the WCF service be the one to start and schedule the jobs?
I think you're overengineering it, possibly.
The Problem: You have a web site which needs to start up jobs on an ad-hoc basis. Other jobs will be run to a fixed schedule. The web site will report on all/any of these jobs.
For running the scheduled jobs, a Windows Service using Quartz is indeed an ideal solution for the fixed schedule part. However, to report on those jobs the data must be collected by the Service and made available. A service can be set up to restart on fail, so you can guarantee that it will always be running (barring a minute or two when it's restarting if it fails - and why should it?. However, any history will be lost unless the Service stores it somewhere it can be retrieve it after a restart.
The simpler solution to the web site getting the history is for the Service to write its data to a database. Then it doesn't worry about a restart: all the history has already been saved, and the data can be read by the web site at any time.
Similarly, if the web site talks directly to the Service (as a WCF Service or otherwise) then what happens if the service is not currently running? The request gets fails until the restart is completed. Frustrating for the user. Alternatively, the web site puts the request into the database. The service monitors the database for requests, and starts jobs appropriately when it sees a new request. If a request is written while the service is not running, when it restarts it will see the request(s) in the DB and execute them.
So I think using a WCF service is overkill, and actually introduces some problems: persistence of history, and what to do about requests made while the service is down. These problems don't arise if you go the way I've described.
Cheers -
Related
Is there some mechanism in WCF that can be used to "pre-start / warm-up" WCF services that are hosted in IIS ?
- something like the warm-up scripts for SharePoint sites
I have the situation where servers are re-booted over night and next day there is a long delay while the WCF services spin-up. I can't change the time-out in various applications that use the services, so the first users are reporting errors in the morning when they go to use their applications
This is on Windows 2003 Server and IIS 6.0, so the IIS Application Pool Warm-Up Module, http://www.iis.net/download/applicationwarmup, as that's for IIS 7.5
NOTE: the module seems to have been temporarily withdrawn, see details on ... IIS Forum
I know you will don't like the answer and I think I repeat myself because it is not the first time I'm posting it. The way to warm-up anything in IIS prior to version 7.5 is using scheduled console application to ping your web site / services and warm them up. It is ugly solution but it works, it is easy and I saw it on every project which had to deal with this requirement.
WCF services should be instantly ready when they start. Just make sure the services are set to automatically start when the server boots.
You can use Windows Server AppFabric, it has Auto Stat feature to keep the service always on. But you need to be on IIS 7.5 to install App Fabric.
The goal is that I want my overall website response time to be instantaneous.
The problem is that I do no have IIS access, my website is hosted using external service and I have no control to the IIS panel.
My current approach now is having a scheduled code that keeps my website alive. The problem with this only approach is the hosting service has an algorithm to shutdown all their hosted website like every some hours.
This is why I need to implement another approach which to warm up / pre-load the website each time it runs.
How to do this when there is no access to the IIS panel?
The solution requires no 3rd party sites; robots; or apps, you merely write a very simple app yourself that periodically performs a trivial web function, perhaps a REST GET. By performing this function say every few minutes not only do you guarentee that the IIS pool won't timeout and be cold for a client, but it also has the nice effect of ensuring your website is up and running in a warm condition (JIT'd; and running) ready for a real request for your non-heartbeat website requests.
e.g.
In your website expose a REST API, say www.misspiggy.com/api/hiyaaaa that does nothing other than to return HTTP 200 OK.
By implemententing this in your ASP.NET app, any request to the above URL will cause your stopped or cold ASP.NET website to be JIT'd during:
first deployment (and even then only during a request is made to it)
after the IIS AppPool has timed out and needs to restart on demand
The client code that makes the REST request can be anything:
a console app
a Windows service
WinForms/WPF app
The console app can be triggered to fire via Windows Task Scheduler say every 5 minutes thus saving you the hastle of building in a scheduler.
My current approach now is having a scheduled code that keeps my website alive. The problem with this only approach is the hosting service has an algorithm to shutdown all their hosted website like every some hours
I suggest you set your ping period to be a matter of minutes rather than hours.
No admin access to server required
The problem is that I do no have IIS access, my website is hosted using external service and I have no control to the IIS panel
It should be pointed out that this solution does not require you to install anything new on the server nor make any changes on the server.
Azure
It is interesting to note that Azure Application Insights has Availability Tests that though designed for testing web site availability, can be used for this exact same purpose of keeping your website alive and warm ready to go for web clients. In fact this is what I do for my web apps.
Doing so keeps response times and latency as low as possible.
There are a number of things you can do but a real simple solution is to use a website monitoring site something like statuscake or uptime robot there are a large number of them out there. You set them up call a page or pages on your website at set intervals to ensure it is still up this has the added bonus of keeping the site warm.
I would also precompile your mvc app if you arent already doing that.
HTH
I'm currently working on a WCF service which holds and processes all the data for an application, while a MySql database is used for persistence. The service currently works as a singleton (InstanceContextMode.Single) and supports multiple concurrent calls (ConcurrencyMode.Multiple). I'm not really sure what version of IIS the service is hosted in, but I believe it is IIS 7.5.
The problem is that there are some situations where if an exception occurs (eg.: while releasing ReaderWriterLockSlim locks), the service will be in a unreliable state and data may get corrupted (and written into the database) if users keep calling the service.
Currently I know of two ways of preventing users from calling the service: either closing the InstanceContext object (through OperationContext.Current) or raising an exception in IDispatchMessageInspector.AfterReceiveRequest if the service is in a faulted state. The problem with both of these two ways is that they make the service unavailable until I restart the server/application pool (which I can't, see note below) or re-deploy the service.
Important note: Although I have Full-Trust, the service is currently hosted on a shared server, so I can't restart the server or the entire application pool (if that is possible) because that would restart other people's services as well.
Update:
I tried unloading the AppDomain as #usr suggested, but that doesn't work as well: after unloading it, an exception is raised for every call to the service.
Currently I'm trying to find out what WCF/IIS uses as a condition to decide if the service should be created again. I noticed that in the code generated for the client checks if there is any channel available to communicate with the service; if there isn't, a new one is created. Thus, I tried to close all channels in the service: I tried closing OperationContext.Current.InstanceContext.OutgoingChannels, OperationContext.Current.InstanceContext.IncomingChannels, OperationContext.Current.Channel, and many other properties with "Channel" in their name, all of them with no success.
The way to warm-up anything in IIS prior to version 7.5 is using scheduled console application to ping your web site / services and warm them up. It's not a good fix but it works, it is easy and I saw it on every project which had to deal with this requirement.
Or If you are using IIS 7.5 then
You can use Windows Server AppFabric, it has Auto Stat feature to keep the service always on. But you need to be on IIS 7.5 to install App Fabric.
We want to synchronize the data in our application with the data of an external service. (Such as accountancy software. This synchronization should be executed every night and when the customer wants to.
I am aware that long running threads don't belong in web applications and this synchronization should be executed within an external windows service. But the downside of this method is, that is becomes harder to deploy / maintain, since the application can be installed on the customer's webserver too.
Is it possible to completely integrate this synchronization with just the use of a class library project withing my solution, which will start up at the Application_Start event?
Since your application is hosted on IIS, it's maintained by the application pool process. If you create additional module for your task, it will be running within context of the same process. You have to be sure this process is still working in the middle of the night, when application is not used, in order to perform the synchronization you want. You can use Quartz.NET to schedule your sync task.
But still, I think much better idea is to perform the synchronization from windows service. Service should communicate with the application for example by using database, where it logs its current activity. It gives you the possibility to monitor of the service state from the web by connecting to such database. I know service forces some additional administration effort, but it will be much more reliable and secure. You can also add service starting possibility from your web application (if pool process user has access rights to windows service) to overcome (or at least minimize) administration effort connecting with restarting your service after some failure.
I've written such functionality, so just to give you an overall look of what I mean by web monitoring of such external service, check the screen below. It can be written with the ajax support to achieve more responsiveness (pooling mechanism), which will be convenient for the end user.
Are there situations that we should use a windows service ?
I am building a client-server project (c#) and the server supposed to work alone without any user so someone advised me to use a windows service to run the server, is this right ? or there are a better solutions ?
Windows services are normally used when an application needs to continuously run. For example if they need to:
Wait for incoming requests. (Like through remoting or wcf)
Monitor a queue, file system etc.
If a program just needs to run periodically, like once a day. It is normally easier to create a scheduled task.
In your situation I would use a service for the following reasons:
You don't need to have a session running. This is good for security, and also reduces overhead on the server.
You get some of the managment commands built in for free
Start
Stop
Pause
Continue
You can handle server events such as shutdown.
Windows service can start running as soon as the machine is powered up, which makes ideal for running as a server, http server for example. No one is required to login.
You should create a Windows Service to run code in the background, without user interaction.
For example, a Windows Service will run even if no-one is logged on.
Any server that accepts connections (such as a mail, web, or FTP server) should usually be a Windows Service.
Well, a Windows Service provides a full framework for your application to work and to remain active while you want it to, so I think its ok.
Windows services are the right thing to use for something that should run all of the time, whether or not a user is logged in.
If you need something to run without an active user logged in, you need to use a windows service.
When you need the application to start running even when no one has physically logged into the machine, which is common with server machines, a service is a good candidate in this case. Especially because the service can be configured to auto start, which means the service will start when the machine is rebooted withut human intervention.
If however you are wanting to host web services (WCF) while a service is an option, you might consider hosting in IIS, this relieves you of writing the actual hosting code etc.