12
votes

The scenario is simple: using EF code first migrations, with multiple azure website instances, decent size DB like 100GB (assuming azure SQL), lots of active concurrent users..say 20k for the heck of it.

Goal: push out update, with active users, keep integrity while upgrading.

I've sifted through all the docs I can find. However the core details seem to be missing or I'm blatantly overlooking them. When Azure receives an update request via FTP/git/tfs, how does it process the update? What does it do with active users? For example, does it freeze incoming requests to all instances, let items already processing finish, upgrade/replace each instance, let EF migrations process, then let traffics start again? If it upgrades/refreshes all instances simultaneously, how does it ensure EF migrations run only once? If it refreshes instances live in a rolling upgrade process (upgrade 1 at a time with no inbound traffic freeze), how could it ensure integrity since instances in the older state would/could potentially break?

The main question, what is the real process after it receives the request to update? What are the recommendations for updating a live website?

3
There is some information on the kudu wiki page on github, but I don't think this answers your question directly: github.com/projectkudu/kudu/wikiRichard Astbury
Richard, thanks for the reference! It does help open up the "under the hood" a bit for git specific deployments. However, it does leave short of answering or eluding to answering my question. It basically references a wwwroot file copy of only changed files from checked-in code.Randy
I think that's all there is, although it does mention deployment hooks as a future feature.Richard Astbury
Richard, thanks for your effort, but the process is still missing. It doesn't illustrate how they synchronize (or don't) rollout, what they do with traffic/active-users, and how they run EF code first migrations only once.Randy

3 Answers

2
votes

To put it simply, it doesn't.

EF Migrations and Azure deployment are two very different beasts. Azure deployment gives you a number of options including update and staging slots, you've probably seen
Deploy a web app in Azure App Service, for other readers this is a good start point.

In General the Azure deployment model is concerned about the active connections to the IIS/Web Site stack, in general update ensures uninterrupted user access by taking the instance being deployed out of the load balancer pool and redirecting traffic to the other instances. It then cycles through the instances updating one by one.

This means that at any point in time, during an update deployment there will be multiple versions of your code running at the same time.

If your EF Model has not changed between code versions, then Azure deployment works like a charm, users won't even know that it is happening. But if you need to apply a migration as part of the migration BEWARE

In General, EF will only load the model if the code and DB versions match. It is very hard to use EF Migrations and support multiple code versions of the model at the same time

EF Migrations are largely controlled by the Database Initializer. See Upgrade the database using migrations for details.

As a developer you get to choose how and when the database will be upgraded, but know that if you are using Mirgrations and deployment updates:

  1. New code code will not easily run against the old data schema.
  2. If the old code/app restarts many default initialization strategies will attempt roll the schema back, if this happens refer to point 1. ;)
  3. If you get around the EF model loading up against the wrong version of the schema, you will experience exceptions and general failures when the code tries to use schema elements that are not there

The simplest way to manage a EF migration on a live site is to take all instances of the site down for deployments that include an EF Migration - You can use a maintenance page or a redirect, that's up to you.

If you are going to this trouble, it is probably best to manually apply the DB update, then if it fails you can easily abort the deployment, because it hasn't started yet!

Otherwise, deploy the update and the first instance to spin up will run the migration, if the initializer has been configured to do so...

If you absolutely must have continuous deployment of both site code/content and model updates then EF migrations might not be the best tool to get started with as you will find it very restrictive OOTB for this scenario.

0
votes

I was watching a "Fundamentals" course on Pluralsight and this was touched upon. If you have 3 sites, Azure will take one offline and upgrade that, and then when ready restart it. At that point, the other 2 instances get taken off-line and your upgraded insance will start, thus running your schema changes.

When those 2 come back the EF migrations would already have been run, thus your sites are back.

In theory then it all sounds like it should work, although depending upon how much EF migrations need running, requests may be delayed.

However, the comment from the author was that in this scenario (i.e. making schema changes) you should consider if your website can run in this situation. The suggestion being that you either need to make your code work with both old and new schemas, or show a "maintenance system down page".

The summary seems to be that depending on what you are actually upgrading, this will impact and affect your choices and method of deployment.

0
votes

Generally speaking if you want to support active upgrades you need to support multiple version of you application simultaneously. This is really the only way to reliably stay active while you migrate/upgrade. Also consider feature switches to scale up your conversion in a controlled manner.