4

This might sound like a very dumb question, so let me first say what I want to achieve and then proceed to my question on how I'd envision something like this working.

I am trying to achieve completely seamless deploys of our web application to IIS (without interrupting users or active connections).

The way I envision this working is to have two root virtual directories sharing the same site. By root virtual directory I mean the one that IIS creates internally and assigns it to the root of each site or web application; except here I want to have two such root vdirs (each bound to their own app pool, but both referencing the exact same application from different folders). During normal operation, one of the vdirs would be inactive.

When doing a deployment, I would put the new code into another folder referenced by the second (inactive) vdir, and then mark it as active. What I want to accomplish is to then have IIS begin sending all new connections (requesting the same site) to that second vdir with the new code, but keeping the old one also alive & active until all remaining connections to it are dead (some, such as file uploads, could be long running). Once all of the lingering connections are dead, the old vdir/app pool becomes inactive and the second one with the new code becomes the only active one.

I hope this makes sense.

If it does not, here is my alternative attempt at explaining it with an example.

--- Web Site ("mysite.com")
    --- Root VDir#1 (IIS Internal, App Pool: AppPool#1, Virtual Path: /, Physical Path: C:\inetpub\MySite.v1084\). ACTIVE
    --- Root VDir#2 (IIS Internal, App Pool: AppPool#2, Virtual Path: /, Physical Path: NONE). INACTIVE

During a deployment, Root VDir#2 would become active and its Physical Path would change to C:\inetpub\MySite.v1085. That would be the default vdir IIS would serve for all new connections. Once all active sessions/connections to Root VDir#1 die, that becomes inactive.

Is something like this possible? Are there alternative ways of doing something like this (I know there is some form of built-in load balancing in IIS ("Web Farms"?) but am not too familiar with it).

11
  • If you persist any state in server memory between requests, this won't work. In-memory session usage is the most obvious one, but there could be other more subtle. Make sure that you do not have them. Feb 19, 2013 at 21:58
  • We do not... Partly because we have complete hardware-level load balancing in production and partly from a dependence on some in-house legacy systems, we do not store any state information at all on the web server (even session information is handled by third party cache server clusters).
    – Ruslan
    Feb 19, 2013 at 22:04
  • Erm. If you have a load balancer then I don't understand a problem. Divert all traffic to a single node (let the old connections die). Update all the other nodes. Divert traffic to updated nodes (let the old connections die). Update the last one. Enable it back. Will this work? Feb 19, 2013 at 22:10
  • Heh, yes, this is currently exactly what we do in Production :) However, I also want to achieve full seamlessness on our Dev, QA and client-facing sandbox environments as well, of which we have quite a few and they all run on single web servers.
    – Ruslan
    Feb 19, 2013 at 22:12

1 Answer 1

1

What you are proposing sounds like an A/B swap. (Similar question)

There is an IIS addin tool from Microsoft called Web Deploy. It will automate most of the physical motions of deploying updated code into IIS but your requirement of seamless migration is the sticky point because you have long-running file-transactions. The best way to handle this is to get a load balancer, run with two production instances of your site at the same time and have a third instance for staging updates.

(BTW, Azure is doing something like this with "Cloud Services" -- there's a "Swap" command to do this exact thing.)

Going back to your particular setup, consider this configuration:

One IIS machine, two Web Sites. Web Site A and Web Site B. They do not point to the same files. They have their own folders. Web Site A is online and serving users in production, while Web Site B is offline. When you are ready to update, you update Web Site B, then swap On/Off Web Site A. Now B is online and A is offline. This is an A/B rotation. Later, when you do your next update, you update A, then swap On/Off with B. Now A is online and B is offline.

That exact moment, when you swap, there is the possibility of losing traffic -- (and you will probably kill those file transfers) but if your app is low volume, maybe no one will notice (you decide). However, if this is mission critical, high volume, site -- get a load balancer and use it as others have described.

What WebDeploy won't do, (as far as I know) is swap On/Off site A and site B. For that, you'll need to write a script and do it at the command line.

The benefit of the Web Deploy + scripts is that you can eventually automate this and maybe tie it into a continuous deployment system.

The long running file transfers are probably impossible to save with this setup. Another challenge is any in-memory state of your app. If your web app was designed with in-memory data, then you'll lose it when you do the A/B swap. If the programmers are using session, you may be able to turn on the session service. The session data will not be in the same process with the rest of the app and might survive the A/B swap. Talk to your programmers about how the app manages in-memory data. Maybe it doesn't actually have any. Maybe it can be easily recreated once the app reloads -- (e.g. rebuilding a cache from database)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .