IIS7 application pools can be recycled programmatically. Is there an equivalent concept for the web role in Azure?
That is the basic question, but for background on why I ask, I include the following...
We are attempting to get Umbraco installed in Azure, and the Umbraco installation wizard writes it's configuration information and then manually restarts the application pool (in IIS) to reread the configuration it just wrote. It needs to work the same way in Azure, but at this point we are not able to get it to reinitialize itself from scratch (as it does in IIS7).
You can call RoleEnvironment.RequestRecycle() for a given role instance. This effectively has the Windows Server VM restart, which re-executes your startup scripts, OnStart() method, and Run() method. When doing this, you may want to consider some type of breadcrumb to leave yourself: If you find something installed upon restart, just skip the install process; otherwise, install and request a recycle.
Related
[I'm posting this to record what I actually found out after hours of painful trial-and-error.]
I have a website that I need to be "always running" (because in this case it has a Hangfire job that's responsible for kicking off a scheduled task every 5 minutes), and by default, websites are only started up when the first request is received.
So, how can I ensure that the website is started automatically? And, how can I configure this via the TFS release management tool?
[This answer isn't specific to Hangfire, but see the Hangfire documentation's discussion of this issue for details of how it affects Hangfire, but note that the recommended work-around is somewhat involved, and much more complex than the solution below. See also a separate and quite comprehensive discussion on the Hangfire support forum that gives several alternative solutions.]
In IIS, each website is associated with an Application Pool (App Pool). You can configure your App Pool to start automatically via IIS Manager by changing the "Start Mode" to AlwaysRunning in "Advanced Settings" for the App Pool:
However, starting the App Pool doesn't start the website (or websites) associated with it. The website does not get loaded until the first request is received.
In IIS8 (or IIS7.5 with an extension), a new setting was added that allows us to work around this. You can ensure that the website gets sent a request as soon as the App Pool starts by setting "Preload Enabled" to True in "Advanced Settings" for the website:
The combination of these settings ensure that the website will automatically start up when IIS starts, and immediately after the App Pool is recycled, etc.
But, how can you get those settings applied automatically as part of a TFS release pipeline, rather than having to remember to set them manually?
In your release definition, you presumably have an "IIS Web App Management" task, which sets up the App Pool and the website. In the configuration panel for this step, there should be an "Advanced" box with an "Additional AppCmd.exe Commands" entry field. You can use AppCmd to apply the settings described above.
AppCmd has the most confusing command-line syntax I've yet seen outside of code-golf competitions, but here's the incantation that worked for me:
set config /section:applicationPools -[name='myAppPoolName'].startMode:AlwaysRunning
set app "mySiteName/" /preloadEnabled:true
Note that if you have configuration variables defined for your App Pool name and website name, then you can use those rather than hard-coding the name, such as:
set config /section:applicationPools -[name='$(appPoolName)'].startMode:AlwaysRunning
I hope this helps somebody... Thanks for listening :-)
I have an app which needs to be installed for all the services I have. Unfortunately, installation requires many files and task related input parameters (e.g. RoleInstanceValue xpath=...).
The way I came up with to share this task among cloud service projects is through Azure Plugins (here is a link to a library of them http://richorama.github.io/AzurePluginLibrary/).
The problems I see with this approach are:
It is not recommended/supported by Microsoft, which means they can
change support for that any time.
It requires copying files to C:\Program Files\Microsoft
SDKs\Azure\.NET SDK\v2.6\bin\plugins\NxlogAzureForwarder, adding an
extra step to build setup.
Microsoft recommends startup tasks. But I could not figure out a way to share them among cloud services.
So, my question is: how to easily reuse startup tasks?
As recommended your best chance would be a startup task that starts your app, which would be encapsulated into a Windows service. That service is going to be your reusable task/app/service (whatever you call it).
What you need extra is the following:
Project reference to your Windows service
An install script for the service
Installer tool
(Optional) app config for your service
To start your app/service you need to update cloud service definition by adding start up task and making runtime context elevated, and start your service in OnStart entry point.
That being said, you can place parameters of your app in the cloud config and read them in your WebRole and pass them to your service.
For more detail check out this post.
I 've found out that Azure websites (trial version) doesn't autostart my node sever process (it starts only when I load the url in the web browser); and that when there are no requests in a while, the process is killed.
I mean, when I git push my server, I would like it to start running immediately and continuously.
I read (here, for example) that this might have to do with the way iisnode manages azure websites, and that I can't do anything to change it. Is this the actual way Azure websites work? Is there any way I can deal with this?
Thanks in advance,
Bruno.
You've find the answer. There is no other answer.
The process termination because of inactivity comes from IIS - there is Idle Timeout setting. Which to my knowledge is not configurable in Azure Web Sites (at least not Free tier). Check out also this SO question and its answer to get better understanding on why you can't change this timeout on the FREE and STANDARD tiers.
And here is an interesting workaround to avoid this idle timeout. Actually if you use technique, you will also have kind-of "auto start", in terms that when your scheduler hits your site after a new deployment, it will "boot up".
This can get a little complicated, but if you don't want to use their 5-min ping service, you can keep these always on by doing the following:
Create an app setting on your website configuration tab within the portal:
WEBSITE_PRIVATE_EXTENSIONS and give it a value of 1
Create a text file named applicationhost.xdt and populate it with:
<?xml version="1.0"?><configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"><system.applicationHost><applicationPools><add name="DefaultAppPool" managedRuntimeVersion="v4.5" startMode="AlwaysRunning"><processModel identityType="ApplicationPoolIdentity" /></add></applicationPools></system.applicationHost></configuration>
ftp into your website and create a folder on the root directory called Site Extensions. (there should now be 3 folders in your root: LogFiles, site, & SiteExtensions)
Create another folder within 'Site Extensions', named ASPLimits
Upload the applicationhost.xdt into the ASPLimits folder
Restart your website using the portal
I noticed that when you RDP to a Web Role instance on Windows Azure to make an iisreset, the World Wide Web Publishing Service shuts down, and the only way to get your role up and running again is either by restarting the aforementioned service or re-roll/restart your instance.
For reasons unknown to me, Windows Azure default the start mode of World Wide Web Publishing Service to Manual, why an iisreset sort a leave your Web Role unavailable to the WWW.
I found a solution to this - IMO - odd behavior, and answered it to the original question of this post.
However, is there an alternative to iisreset on Windows Azure - maybe programmatically where I can pinpoint the exact instance? Because that is another issue; now I have to use RDP to each instance .. it would be nice if it was possible to do a pinpoint each instance.
Think about it; i have a CNAME to www.awesome-azure.com; this is hosted by 3 instances in round-robin, and I want to reset/monitor/diagnose/heartbeat each one through a REST API (ir similiar), and not like now - through RDP.
Can this be achieved.
EDIT
Tried to make it more clear what the challenge is as well as the goal to achieve.
EDIT 2
Provided a solution to the iisreset challenge; updated the question to pinpoint instances over the Internet if possible.
Well, I still don't know why Microsoft Azure decides to set World Wide Web Publishing Service to start mode Manual, but I found a way to change it.
To the second part of the original question I still hoping for an answer, but until then, please find my solution for the first part to fix the (IMO) iisreset problem with Startup Task:
In your startup.cmd (or what ever you have named it) which I have placed in a startup folder in the root of my application, include this line of text:
powershell -ExecutionPolicy Unrestricted .\startup\w3svc.ps1
In the same folder, create a PowerShell file named w3svc.ps1 with the following content:
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\W3SVC -Name Start -Value 2
Voila; your IIS now works as expected - World Wide Web Publishing Service is now set to start mode Automatically.
Note: for the above to work, you need to have your osFamily property set to 2 in you ServiceConfiguration.cscfg file.
You can handle the RoleEnvironment.Changing event in WebRole.cs and set the Cancel property on the event arguments object to true. Then you just need to make a change to the configuration settings and Azure will restart all your instances in an orderly fashion.
I don't know why iisreset isn't working. As to your second question, you can use the Service Management API to reboot or reimage an instance. That might do what you want. You could also, of course, write your own code to do whatever you want. (You could have code in your web role that polls a blob called <instance ID>.txt and does an iisreset any time the blob changes.)
I hosted my asp.net mvc3 application on amazon ec2 cloud using windows server 2008 R2. The first time page loading is very slow. I decided to enable auto start on IIS 7.5.
I followed Scott's post.
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx
I only have one web application hosted on this server, and this application got its own app pool, not shared with anything else.
this is all I did, add startMode="AlwaysRunning".
here's hte problem. I see performance gets a little bit better, but still about 4-5 seconds.
Is there way to verify if my auto-start setting acutally works?
If you have access to IIS Manager on the box, you can examine "Worker Processes" for the site. Otherwise, look for a process named w3wp.exe. If you only have one site, it should be the only process.
Try stopping the application and confirming the worker process has stopped. Now start the application without issuing a request. If the process is there, auto-start is working.
EDIT: Slides 11 and 12 from http://www.slideshare.net/brianritchie1/iis-alwayson-services may be helpful.