Note: I couldn't decide whether this was more appropriate for Stack Overflow or Serverfault, so if you have some insight into that, let me know.
Background: Recently, my server (Windows 2000, MS SQL 2005, IIS 5.0, ASP Classic) experienced a spike in traffic to a specific set of ASP pages. This spike caused a massive drain on the processor, spiking it at 100% and causing all kinds of timeout problems for the visitors.
We've actually handled larger volumes in traffic than this without error. The problem seemed to be that the specific ASP scripts being called were using a huge amount of processor time. Using the Process Explorer from Sysinternals, I found that dllhost.exe was taking up all of the processor time. Looking at its threads, the culprit was calls to COMSVCS.DLL, which seems to be COM+ objects.
So, it seems like my ASP pages are calling COM+ objects and it's killing my processor.
Here's the question: How do I determine which parts of my ASP scripts are calling the COM+ objects, and how would I begin to improve performance from these parts? I have basically no background in Windows programming, so I am at a loss of how to begin.
Thanks for your help.
Neither COM+ or DLLHOST are likely your problem, they are just the containers that the web site and COM objects are running in. The actual objects they are being "fed" are your issue and/or the ways/frequency they are being called by the web app.
A more productive way to isolate the problem would be to look at the IIS logs for the pages with the longest processing time and have a programmer analyze what is going on in that page and what objects are being called.
Specifically, check the "time-taken" column in the IIS log.
For determining what objects are being called, look for
<OBJECT ID=MyObject RUNAT=SERVER PROGID=MyDll.MyObject></OBJECT>
or
set myObject = server.createobject("MyDll.MyObject")
inside your ASP pages.
Beware that this could be calling standard DLL (not COM+ objects). The method for instantiation is the same for both types.
If you want to know what COM+ processes are you running, check out the Component Services app.
alt text http://img38.imageshack.us/img38/5062/capturerm.png
Related
Whenever I deploy a newer version of my .Net Core 2.2 Web API, the first time the API is called by the consuming client (such as a GET), it takes a while for it to reply. Subsequent calls to the API are then fast. I believe this is because the first time a .Net Core web app is called, after the files having been updated, it has to do a quick re-build/re-compile (not sure what the correct term is).
Is there a way to get the API to be automatically re-built/re-compiled after publishing it? I'm using Visual Studio 2019 Community.
Thanks
There is no rebuild/recompile here. The published app is already compiled. You haven't given us any information about your hosting situation, but some means of hosting will take longer than others to restart. For example, if your running in IIS, the App Pool literally shuts down and restarts, which takes some period of time. The app itself also has a startup period, namely running everything in Program and Startup. That should be relatively quick, but can be slower depending on what you're doing there. For example, if you're migrating your DB at startup (an antipattern, but one many people use), that's obviously going to add some time to the startup.
Also, .NET Core is a JITted runtime. The compilation process actually produces what's know as IL code. This IL code is then run on the runtime, just in time, hence JIT. However, the IL code can be constructed to optimize for different run scenarios. What's good for startup speed isn't necessarily good for steady-state performance and vice-versa. The runtime takes a balanced approach, optimizing for reasonable performance both on startup and steady-state. Starting with .NET Core 2.1, the idea of tiered compilation was introduced. It's complicated, but it essentially amounts to compiling the application twice: once for optimal startup and once for optimal steady state. Then, then the different compilations are swapped in or out depending on the status of the application. This enables faster startup and better steady-state performance. It has to be turned on with a tag in your project file, though, if you want to use it:
<TieredCompilation>true</TieredCompilation>
Finally, .NET Core 3.0 has made greater strides here, both in improving tiered compilation and in introducing the ability to compile to native. Native compilation removes the runtime entirely, so everything runs right on the metal. That's going to obviously give you the best performance, but it's also the most persnickety, as you have to compile for the exact destination, down to the architecture, OS, and even version. However, it's not yet available for ASP.NET Core apps. Still, it's something to keep on your radar.
Today I've been working with wkhtmltopdf.exe in a web app and I was wondering whether I should use a lock (or the singleton pattern) in order to call Process.Start in a thread-safe manner.
My concern is that multiple users will do GETs simultaneously on the page that calls the exe file mentioned above. It's my understanding that each Request is created on its own thread, does this mean that calling an exe file (with Process.Start) is thread-safe in a web application?
Process.Start has nothing to do with thread safety. It is a thread safe call - you can call it as many times you want from as many threads you want. The problem that comes with this is that you are depending on an external process to do the job. Spawning multiple processes in an intensively used web application is not a good idea as you will be consuming more and more resources. So while this could be fine if your site doesn't have a big load, it is not recommended if you expect to start scaling.
Yeah, I know that converting HTML to PDF in a reliable and performant way which doesn't involve spawning processes and be happy with the final result costs money. But scalability of a web application usually comes at a cost.
I work on a Classic ASP web application that uses several old COM components written in VB6. All of the VB6 components are registered in a COM+ application that run in their own dllhost process. A large majority of the application has been converted to .Net, but there are still a lot of legacy pages and components. COM Interop is used in both directions, calling some .Net assemblies from classic ASP and VB6 as well as calling VB6 components from ASP.Net. The application is running on Windows Server 2008 R2 (IIS 7.5) in the classic pipeline mode.
For the most part the application works fine. The transition to .Net effort was ultimately abandoned, with a new product being developed instead. In the meantime, the old product must be maintained in it's heterogeneous state.
I am having trouble tracking down an intermittent problem where the web application hangs. Users just see a blank screen while their browser waits and the server never responds. The hang persists until I manually kill the dllhost process that's hosting the VB6 components, so I believe the problem is buried there. Probably a memory leak or runaway circular loop.
There are thousands of users on the system daily, but the problem only happens once or twice a week. Fortunately we have a web farm that automatically pulls a server out when it stops responding, so the customer impact is zero. Still, I would like to figure out what's going on.
I have recompiled all of the VB6 components to include debugging symbols and redeployed to production. When the problem happens, I use the 32-bit task manager (c:\windows\syswow64\taskmgr.exe) to take a crash dump of the dllhost process. I end up with a dllhost.dmp file, which I bring down to my development workstation and open in VS2010. I have the .pdb symbol files that VB6 created in my symbols path. When I start the debugging session in VS2010, I can go to the Modules screen and see that indeed all of the symbols for my components are loaded.
Where to go from here? The call stack doesn't show any of my own components. It looks like this:
The disassembly at the top of the call stack looks like this:
Not sure what else I can do. I examined all of the locals at every frame of the call stack and it's gibberish to me. I don't see any references to any of my own components.
Perhaps WinDbg would yield more information? Not sure where to start with it.
I'm pretty sure that if I could just find what VB6 class/method was being called when the hang occurred that I could get to the bottom of it. I've tried adding some logging, and the results are inconsistent.
Perhaps there's nothing wrong with my VB6 components at all, but I'm hitting on some bug within Windows or IIS?
Any advice would be appreciated, but throwing away VB6 is not an option at this point. Thanks.
Not a complete answer, but CoRegisterSurrogateEx is documented to block as long as the surrogate process is running:
The CoRegisterSurrogateEx function is a blocking function. It does not
return until COM+ has determined that the process will be shut down.
Before calling this function, initialize COM on this thread as a
multi-threaded apartment (MTA).
So I don't think the error is on this call-stack. (You can see it was still blocking on a WaitForSingleObject call, most likely the mechanism it uses to block until the process is to be shut down).
I imagine it's possible to wrap asp.dll inside an .exe so that Active Server Pages functionality can be run on any web server (e.g. mongoose) which does CGI.
Has anyone done this before? Ideally, a compiled asp.exe would answer my question :-)
Runner up would be information on how to make a cgi-compliant exe because I reckon I can handle wrapping the asp.dll. Basically all you have is a request on stdin and a response on stdout tright?
Too long for a comment:
Somehow I get the feeling this would be a huge licensing violation for asp.
Never mind the obvious question of Why Bother? (Rhetorical)
Considering you get IIS for free on a MS machine, it would be assinine (IMHO) for a developer to try and get asp running outside of IIS. There's no benefit and a huge potential of failure.
Next, I'm willing to bet a huge sum that asp.dll is not portable to a non-ms server... eliminating the concept of running classic asp on say a linux box... Which mongoose is generally used for.
Consider this a gentle suggestion to preserve your sanity and legal butt: Abandon this whole idea.
I need to develop a very simple class developed as a Windows Script Component that needs to work in a multi-threaded environment.
I am wondering just how thread safe Windows scripting Components are and the scripting engine that executes those components.
In VB6 if a compiled DLL was not compile with "Retain In Memory" and "Unattended Execution" set definately caused problems in a multi threaded environment, I experienced this 1st hand and spent weeks trying to locate the issue with a 3rd party DLL.
Would anyone happen to know what way Windows Scripting Component works, are they intrinsically thread safe (once we don't do anything non-thread safe in the components we write).
I realize that the Windows Script Components are COM Apartment threaded and may not be the most performant things in the world but I have no choice about this.
Kind Regards
Noel
we're found under exterme load testing that WSC components are perfectly thread safe.