IIS7 - only serves up one page at a time. It's

2020-02-03 06:26发布

问题:

Situation: Classic ASP application, using a custom Application Pool. Default settings.

On some IIS7 machines, IIS decides to serve only one page at a time. So if multiple load any pages from a site, each one has to load in succession.

e.g. If I load http://foo.com/default.asp from one browser, and from another machine I load http://foo.com/differenturl.asp, the first has to finish before the other will load. It's almost like the w3p process is single threaded.

Note, there is a setting called MaxProcesses in the Advanced Settings for IIS that says "Set this to greater than 1 to create a Web Garden" (whatever that is). This does NOT solve the problem because this spawns multiple processes with their own session state etc, and when you load http://foo.com/default.asp there's no way to guarantee you get assigned to the same process.

The problem revealed itself because we have a diagnostic page which is written in ASP that creates and ActiveX control which loads a url on the website and returns the results.

So, diagnostics.asp loads and in the code on the server side it creates a small web control that loads (think XMLHTTP control) default.asp on the same server.

This page will NEVER finish loading, because the server is waiting for the diagnostics.asp page to finish before it serves the default.asp page. Deadlock!

This works fine on every IIS6 machine out there, and I believe there are some IIS7 servers where it works fine too.

I've verified it's not a result of our quirky diagnostic either. Loading multiple tabs from one machine, or even separate machines will show that the web process handles them one at a time.


Correct Answer by AnthonyWJones: Server Side debugging was turned on in IIS7. This puts IIS into single threaded mode.

回答1:

In IIS manager click on the application in the tree.

Double click ASP under the IIS section.

Expand "Debugging Properties"

Ensure both "Enable Client-side Debugging" and "Enable Server-side debugging" are set to false.

When debugging is enabled ASP is limited to processing one request at a time in a single threaded manner.



回答2:

First of all: Make sure you test this with multiple clients. A single computer makes only 2 HTTP requests at the same time to the same server (IP adress). (This is an RFC speficiation.)

If that does not resolve your problem, take a look in IIS7 -> ASP -> Services -> COM Plus Properties -> Execute in MTA. Try to set this setting to "True".

Hope this helps.



回答3:

Are you sure you don't have a dependency in your code which is causing the deadlock. I've seen this before where logging, sql connections etc creates a dependency. Use perfmon and check the hard disk read/write queue, memory read/write queue to see if things are backing up.

I would highly recommend Tess Ferrandez's (ASP.NET Escalation Engineer - Microsoft) blog for lots in insights and way to find out what is happening. Tess has forgotten more about this stuff than most people will ever know.

I think your problem is not IIS related but something in your app, probably in your ActiveX component. Make sure you clean up after your ActiveX component. Here's a piece of code I use to clean up after using Excel (Another Com component). Remember Com is not managed.

    Private Sub ShutDownExcel()
    If objExcel IsNot Nothing Then
        objExcel.DisplayAlerts = True
        objExcel.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(objExcel)
        objExcel = Nothing
    End If

    ' Clean up memory so Excel can shut down. 
    GC.Collect()
    GC.WaitForPendingFinalizers()

    ' The GC needs to be called twice in order to get the 
    ' Finalizers called - the first time in, it simply makes 
    ' a list of what is to be finalized, the second time in, 
    ' it actually the finalizing. Only then will the 
    ' object do its automatic ReleaseComObject. 
    GC.Collect()
    GC.WaitForPendingFinalizers()
End Sub

Hope this helps.



回答4:

IIS7 is most certanly multi threaded, so I would guess there is a problem with your app.

You mentioned ActiveX to load a page from same server - maybe this ActiveX isn't free threaded and this causes every page that uses it to run single instance?

BTW: Web Garden - same server useing multiple processes - cannot use inprocess session Web Farm - multiple web servers



回答5:

Ensure that asp.net is configured to use more than 1 worker thread. This msdn article explains how to set this configuration option.



回答6:

Just a thought but if you go to the website in IIS, click the Limits... link on the left, what are the connection limits set to? There is both a max bandwidth and max concurrent connections options there.

I would also go to the App Pool and click Advanced Settings... and check the CPU and Memory limits. Possibly even creating a new app pool from scratch with No Managed Code selected to eliminate it.



回答7:

Have you changed "Managed pipelined mode" on Application Pool to "Classic" (default is "Integrated")? If not, try with classic.

I don't know if it would help in any way. I have long ago ceased to fight to get classic ASP apps to work with IIS7. (Not that I can say, the apps are truly nice and correct, but they worked in earlier versions.)

And try turning buffering off for test pages and make them spit something out in each iteration. Buffering (and caching) might've changed in IIS7. Maybe they are processed concurrently after all and simply buffers are too big to see the difference.

That's all that comes to my mind right now.


I assume you are testing with very simple case. Your app doesn't (neither test pages nor global.asa) use any strange objects that are common to both requests and so need locking.



回答8:

If it isn't an issue with the debug settings, I've found that you can experience similar behavior when using session variables in ASP in IIS 8.

I don't know that this is IIS 8 specific, but "ASP guarantees that only one request from a Session will be executing at any time." http://msdn.microsoft.com/en-us/library/ms972335.aspx