共用方式為


HOWTO: Provision ASP.Net AppDomains and IIS6 Application Pools

This is a frequent source of confusion - how ASP.Net and IIS does application isolation. The key point to remember is that IIS runs native code and thus relies on NT user identity (and thus NT process) for isolation, while ASP.Net runs managed code with CAS and thus can run its own isolation mechanism within a NT process.

Question:

I read somewhere that running applications in different pools takes up more memory. My understanding of asp.net is that all applications run in their own space under the shared memory space inside w3wp.exe. process.
1. So how is that different from creating seperate pools?
3. Is there a free software to simulate about a 100 connections to a site?
2. Lets say i do run applications in different pools and limit the mem to 10 MB per site, and set it to recycle once limit is reached. Will that be better?

I have a webhosting server with 50 sites and 1 GB ram. (so 50 X 10 = 500 MB) approx

Some of then do take up quite a bit of mem so i can set those up with more space.

Can someone provide me with link or some info on this?

Thank you

Answer:

I do not understand what you mean by "all applications run in their own space under the shared memory space inside w3wp.exe process" because I think that is where your understanding goes awry. Here is how I view ASP.Net applications and IIS:

  • The basic unit of isolation for an ASP.Net application is its AppDomain. There is exactly one ASP.Net application per AppDomain
  • Every AppDomain identifies and "owns" some portion of the URL namespace. i.e. /ASPX1/WebApp.aspx
  • IIS6 running in Worker Process Isolation Mode partitions the entire URL namespace of the server to be serviced by arbitrary number of Application Pools (minimum of one Application Pool)
  • Application Pool configuration controls the number of NT processes that service the Application Pool (minimum of one w3wp.exe)

Since configuration of Application Pool is arbitrary, it means that it is possible to:

  • Run multiple AppDomains inside of one NT process

    i.e. "/" is serviced by DefaultAppPool, /ASPX1/WebApp.aspx and /ASPX2/WebApp2.aspx are ASP.Net Applications in their own AppDomain, and both AppDomains are sharing the same AppPool and hence same process

  • Run one AppDomain per NT process

    i.e. /ASPX1 is serviced by AppPool1 and /ASPX2 is serviced by AppPool2, /ASPX1/WebApp.aspx and /ASPX2/WebApp2.aspx are ASP.Net Applications in their own AppDomain, so each WebApp is in their own Application Pool and hence their own process

  • It is not possible to run one AppDomain over multiple NT process

In general, it is a poor idea to isolation ASP.Net applications by using Application Pools. Why?

  1. ASP.Net applications all require the .Net Framework, which is a fixed overhead (in the neighborhood of at least 20MB RAM) paid by every process that loads an ASP.Net application. Suppose you have 10 ASP.Net applications. If each application is in its own Application Pool, you can have up to 10 copies of the .Net Framework loaded in memory by each w3wp.exe of each Application Pool. Efficiency says that you really only need one copy of the .Net Framework for all of the ASP.Net applications, and this is possible only if all 10 ASP.Net applications are in the same Application Pool.
  2. ASP.Net applications do not benefit from Application Pool based isolation (by process identity) because ASP.Net runs managed code, which already has CAS and does NOT rely on user identity nor process space for isolation. AppDomain is the logical concept that is enforced by ASP.Net to isolate the ASP.Net applications. Of course, this is a different story for native code applications like ASP, ISAPI, CGI which do benefit from using process space for isolation.

Thus, if you isolation ASP.Net applications using Application Pools, not only are you wasting system RAM resources loading duplicate .Net Framework libraries into memory, you are also gaining no isolation benefits. It is a lose-lose configuration.

For a webhosting server, I recommend creating one Application Pool for use by all ASP.Net applications, and you configure this Application Pool to turn off all health monitoring checks except for private memory limit at 60% physical memory. In particular, you want to turn off periodic recycling and idle timeout, both default values that wreck havoc with ASP.Net because they periodically recycle the worker process and thus causes the subsequent request to re-load the .Net Framework into memory, which takes non-trivial amount of time.

For ASP/CGI/ISAPI based applications, you should still isolate them by Application Pool and use the default IIS6 settings as base guideline, plus any others that you want

As for how to distribute Websites amongst Application Pools, I would first determine the necessary isolation between the websites (ASP.Net applications should share the same application pool while native code applications of different websites should be separated into different application pools), then calculate the memory footprint of each w3wp.exe of each possible Application Pool, and make sure the system can handle that (and have like 256MB remaining buffer for the host OS's use).

In other words, just blindly isolating websites by creating Application Pools that have unique Application Pool Identites will quickly get you into trouble. Efficient provisioning requires that you analyze what sorts of applications you are running, how the applications need to be isolated by each other, and the representative memory footprint of each application - so that you can make sure it fits within the server's hardware limits or whatever availability guarantees you are making.

//David

Comments

  • Anonymous
    September 02, 2005
    Thank you for the detailed explaination David.
    So w3wp.exe is the NT process and each domain's app runs in its own AppDomain inside w3wp.exe is this correct?
    Something like this
    w3wp.exe
    ---- AppDom1 (domain1.com)
    ---- AppDom2 (domain2.com)

    My webserver has about 900 domains and each of these have their own aspx apps.
    My server stops serving aspx pages intermittently. When I check the RAM and CPU, I dont see any problems.

    Rebooting the server or ending w3wp.exe from task manager fixes the problem. So at this point is it safe to say that an application within an AppDom is causing this? If so how it it possible, that it affects the other AppDoms?

    What is the purpose of the application pool option in IIS? If not to seperate these applications?
    Sorry for all the questions, I seem to have confused myself with all this.

    Thank you

  • Anonymous
    September 02, 2005
    Two questions -

    1) So what is the effect of web gardening on all of this?

    Obviously we'd have multiple W3WP.EXE's, each with their own .Net framework loaded. We'd minimize the impact of the "non-trivial amount of time" to load the Framework, since another process would be available to service the request.

    2) For internal sites, we use AppPool Identity as a means of controlling SQL DB access (Our SQL servers only use Windows Integrated Authentication, not SQL authentication). How is this different then using the ASP.NET web.config Indentity Impersonate?

    With App Pool Indentity, the whole w3wp.exe runs as a given user, with web.config Indentity, is it just the AppDomain?

    Thanks! Your blog has got to be one of the most helpful comming out of Microsoft.

  • Anonymous
    September 05, 2005
    Robert, Christopher - good questions, and as I started writing the responses I realized that I can better answer each of them as separate blog entries (because there's lots to explain), so I am going to do that. I will link to them as comments from here when I get done.

    The short answers would be:
    Robert - AppDomain only prevent code from directly affecting each other, but have you isolated all other commonly shared resources (including the fact they share the same w3wp.exe). Application Pools isolate applications by process, not AppDomain, so no direct correlation between the two as far as the logical concept of "isolate these application" is concerned.

    Christopher - Web Garden does not minimize the impact of the "non-trivial amount of time" at all. I will need to explain how Web Gardening works because it is rarely used correctly. As for user identity executing code on IIS, ASP.Net gives the same options as IIS except they are ASP.Net pages-only and configurable via web.config.

    //David

  • Anonymous
    September 06, 2005
    The comment has been removed

  • Anonymous
    September 06, 2005
    Actually, there is a specific reason to use application pools, if you have several different web apps as well as a database, and the requirements are that 1) database passwords are not stored in config, 2) not hardcoded, either, and 3) each app has a seperate password.

    In my experience, this means that you use windows authentication, and that the application pool's security account be set per pool. Actually, I can see this being a pattern for any sort of per-app security, where part of the security is outside of the CLR's control.

  • Anonymous
    September 06, 2005
    The comment has been removed

  • Anonymous
    September 06, 2005
    kfarmer - actually, I would rephrase your reason as:

    "If your application takes advantage of Application Pool properties, such as process identity, healths-monitoring metrics, etc, then it makes sense to isolate them by Application Pool."

    In your case, you are probably hard coding username/password in IIS Application Pool configuration, and then you run ASP.Net application with impersonate="false" so that ASP.Net code uses the process identity to perform actions while you can still use Windows authentication to authenticate the users.

    Another alternative could be to hard code the username/password in IIS Anonymous User account at a per-App level, and then you run ASP.Net application with impersonate="true" so that ASP.Net uses the impersonated identity to perform actions while you can still use ASP.NET Forms authentication (enable only Anonymous authentication in IIS) to authenticate the user.

    The latter scenario would NOT need an Application Pool for isolation nor user credentials (because anonymous user account is isolating it for ASP.Net at a per-App scope).

    //David

  • Anonymous
    September 07, 2005
    David - you said "reliability testing (simulated user activity/request load)"

    What tools did your team use to simulate this load? What was the testing methodology?

    We would like to find our "sweet spot" in terms of isolation vs. density

    Thanks,
    Mark

  • Anonymous
    September 11, 2005
    Thank you Mark and David,
    Thats exactly what i was looking for. Yes my servers host a lot of sites and sometimes one bad app causes other aspx apps to stop resonding. And this is why i seperated sites, that i suspected, into a different pool. I have informed the customers with the bad app to do something about their code.
    Thank you again for all the info really helped a lot.

  • Anonymous
    September 12, 2005
    Mark - we actually custom built a test application and load simulation tool because we would dynamically exercise the test application and no tool contained the necessary state management which would not end up being a custom script anyways - so we just cut the hassle of the tool out of the picture.

    We really did not worry about measuring a "sweet spot" since we wanted to measure reliability in terms of detectable downtime - so we just cranked up enough client machines to keep the server busy at some predefined threshold and let the simulation vary over time.

    //David

  • Anonymous
    September 13, 2005
    The comment has been removed

  • Anonymous
    September 16, 2005
    The comment has been removed

  • Anonymous
    October 05, 2005
    Dave - And regarding your followup -

    You can treat ASP.Net applications like ASP applications except each has greater RAM/CPU resource requirements and isolate appropriately.

    Realistically, this just means that given comparable HW and Application Isolation requirements, you end up with less dense ASP.Net application deployments than ASP.

    There is no magic to allow apps to share common resources for efficiency yet not have bad apps bring down good apps using the same resources.

    //David

  • Anonymous
    November 12, 2007
    The whole purpose of Application Pooling and process identity is not to just manage resources (or mismanage, as is supposed here) but really to control security. In theory, you WANT to use App Pooling so that a devious user doesnt setup an account or web app that takes down a server, then turns around and takes control of it. Thats why identities in separate pools are beneficial. Its all about security. If thats at expense of resources, then buy a bigger server! - stormy

  • Anonymous
    February 06, 2008
    I have to agree with stormy 100%. Especially for being a web host, security should be #1 over ram anyday.

  • Anonymous
    December 05, 2009
    Wow.  I just read through this thread and a couple of related ones and I can only say I wish I would have found this resource years ago.  Amazing, simply amazing. Of course what brought me here is my problem... at least I think I have a problem.  Hopefully I can explain it well enough. We have several apps running on IIS 6.  We use application pools, mostly on a per app basis.  I noticed a couple months back that one of our apps appeared to have stopped using it's configured pool.  How I realized it was twofold - one, there was a performance issue.  Two, the user name when monitoring activity was no longer the app pool identity; it had reverted to the login ID (UID).  I found that a developer had accidentally moved a web.config file that had pooling set to false.  Problem solved. Several months later, after other performace issues had surfaced and some of our apps were moved to different servers to distribute the load, I am seeing this same indication - the apps are showing up with the UID instead of the pool identity which leads me to believe the pool is not being utilized.  However, I am at a loss to determine why (or if the symptom is truly indicative of the pool not being used). I have gleaned a couple of things from this thread and the other pool threads (different frameworks using the same pool, but I don't think that is the issue here, as currently it is pretty much one app per pool). So I ask, is the symptom (seeing the UID rather than the pool identity) really indicating a problem and if so, what are the things that would cause what appears to be a correctly configured app pool from being used.  We've recreated them with the same result. Thanks to everyone in advance, and special thanks to David for putting so much into this resource. Cheers, ~Dave

  • Anonymous
    December 07, 2009
    After much wrangling, it was discovered that we have set up the identity on each of the machines (I guess as a method to allow pooling to work without domain level security... ?) and at least one of those identities did not have the same password as the others. It fixed the issue. Thanks!!! ~Dave