使用WMI \ ADSI(C#)启动应用程序池重新启动后立即挂起
我遇到了一种奇怪的情况,那就是在使用WMI或ADSI后立即从Windows服务(用C#编写,设置为“自动”启动)启动应用程序池服务器重新启动挂起。使用WMI ADSI(C#)启动应用程序池重新启动后立即挂起
我将描述该问题:其中包含以下主要过程
我们正在开发一个大型应用程序(Windows 2003 Server的SP2,IIS 6.0)(这些进程正在使用Windows服务启动程序时调用初始化&应用程序启动):
1)XServer1.exe,XServer2.exe - 这些进程是本地COM-Exe服务器,包含一些逻辑,但主要通过DCOM将COM对象提供给其他进程(主要是.NET2COM interop调用&纯粹的COM调用)。例如,一些经典的ASP“应用程序范围静态对象”(w3wp.exe)是在这些进程中“活”的COM对象。
2)dllhost.exe - 这是一个COM +应用程序。我们的一些DLL被加载到这个进程中,它充当“状态服务器”(与ASP.NET超出会话服务器相同的想法,但对于经典的ASP页面)。 3)不同的IIS应用程序池(我们称之为appPool1 \ 2 \ 3) - 我们的ASP页面,ASP.NET页面,WCF服务等的容器。这些代码(本地C++ COM dll & C#)应用程序池(w3wp.exe)通常会对(1)&(2)中描述的进程执行DCOM调用。只有appPool1可以配置为Web Garden。
为了开始\停止我们的应用程序,我们编写了一个控制这些过程的Windows服务(C#)。我们的服务过程称为XWinService.exe。该服务依赖于以下窗口服务(名单开始前4个的服务,不断尝试的上榜这样的...):
W3SVC
aspnet_state
COMSysApp
DCOMLAUNCH
Winmgmt的
lanmanserver
lanmanworkstation
seclogon
浏览器
TermService
的应用程序的停止程序(由服务实现)的总结:
1)停止所有3 IIS应用程序池(appPool1 \ 2 \ 3) - 这是为了防止w3wp.exe进程在应用程序关闭时跳转活动。这是通过从WMI C#(system.Management.dll)
2)停止XServer1 \ 2.exe
3)停止COM +应用程序(DLLHOST.EXE)来实现。
应用(通过服务来实现)的启动过程的总结:
1)执行停止过程 - 这保证了它的时间之前没有HTTP的攻击会唤醒W3wp.exe进程。
2)调用&初始化XServer1 \ 2.exe COM-Exe服务器 - 在任何w3wp.exe调用之前需要初始化。只有在一些对象被初始化后,w3wp.exe才能访问这些服务器。这是由.NET2COM InterOp(最终是DCOM)实现的。
3)调用&初始化dllhost.exe(COM +应用程序)进程 - 这是由ComAdmin目录API(C#)实现的。
4)启动我们的3个应用程序池 - 这允许传入的HTTP命中来唤醒w3wp.exe进程并开始服务请求。
这是负责启动\停止应用程序池(WMI)的C#代码。这段代码在我们的服务流程运行(XWinService.exe):
ConnectionOptions co = new ConnectionOptions();
ManagementScope scope = new ManagementScope(@"\\localhost\root\MicrosoftIISV2", co);
foreach (string appPool in AppPools)
{
string objPath = string.Format("IISApplicationPool.Name='W3SVC/AppPools/{0}'", appPool);
using (ManagementObject mc = new ManagementObject(objPath))
{
mc.Scope = scope;
if (Operation.ToLower() == "start")
{
mc.InvokeMethod("Start", null, null); // ### The problematic line of code ###
}
else if (Operation.ToLower() == "stop")
{
mc.InvokeMethod("Stop", null, null);
}
else if (Operation.ToLower() == "recycle")
{
mc.InvokeMethod("Recycle", null, null);
}
}
}
现在的问题:
之前手动重新启动服务器,启动服务(从SERVICES.MSC工具)成功没有任何问题。另外,停止它是好的。我们已将服务设置为启动“自动”,即在服务器(Win2K3 SP2)启动并重新启动服务器时启动。当服务器启动时(登录屏幕出现),我们的服务“卡住”(状态=“开始”),并将永远不会(挂起2天!)开始。
判断的处理陶醉以下:
1)XWinService.exe过程被困在(###上面###)的代码有问题的线路。这被绞死了2天,直到我们杀死了这个过程。请注意:关闭应用程序池(启动过程以停止过程开始)没有挂起!
2)在这个“挂起”期间,从XWinService.exe中的一个DUMP文件(带有DebugDiag工具)中,我们可以看到正在等待的线程。这是它的(本地)堆栈跟踪:
Thread 6 - System ID 2784
Entry point mscorwks!Thread::intermediateThreadProc
Create time 11/19/2009 1:40:05 PM
Time spent in user mode 0 Days 00:00:00.078
Time spent in kernel mode 0 Days 00:00:00.781
This thread is making a COM call to multi-threaded apartment (MTA) in process 884
Function Source
ntdll!KiFastSystemCallRet
ntdll!NtRequestWaitReplyPort+c
rpcrt4!LRPC_CCALL::SendReceive+230
rpcrt4!I_RpcSendReceive+24
ole32!ThreadSendReceive+138
ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+112
ole32!CRpcChannelBuffer::SendReceive2+d3
ole32!CAptRpcChnl::SendReceive+ab
ole32!CCtxComChnl::SendReceive+1a9
rpcrt4!NdrProxySendReceive+43
rpcrt4!NdrClientCall2+206
rpcrt4!ObjectStublessClient+8b
rpcrt4!ObjectStubless+f
….
该线程调用(通过DCOM)的过程884的组成部分,这是中svchost.exe,运行以下服务:AeLookupSvc,AudioSrv,浏览器,CryptSvc ,dmserver,EventSystem,helpsvc,lanmanserver,lanmanworkstation,Schedule,seclogon,SENS,ShellHWDetection,TrkWks,winmgmt,wuauserv,WZCSVC。
正如您所看到的“winmgmt”服务(负责WMI)在此过程中运行并且我们的服务依赖于它,所以我们的服务将在winmgmt启动后启动(对于IIS W3SVC服务也是如此)。
svchost.exe进程(884)被转储,我们可以看到一个线程(等待DCOM调用结束)访问进程2880这是 - wmiprvse.exe(我猜这是WMI服务器。知道它是否有相关性,但是这个过程有两个实例)。这是线程的本地调用堆栈(在svchost中。exe文件):
Thread 48 - System ID 3816
Entry point wbemcore!CCoreQueue::_ThreadEntry
Create time 11/19/2009 1:40:56 PM
Time spent in user mode 0 Days 00:00:00.00
Time spent in kernel mode 0 Days 00:00:00.00
This thread is making a COM call to multi-threaded apartment (MTA) in process 2880
Function Source
ntdll!KiFastSystemCallRet
ntdll!NtRequestWaitReplyPort+c
rpcrt4!LRPC_CCALL::SendReceive+230
rpcrt4!I_RpcSendReceive+24
ole32!ThreadSendReceive+138
ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+112
ole32!CRpcChannelBuffer::SendReceive2+d3
ole32!CAptRpcChnl::SendReceive+ab
ole32!CCtxComChnl::SendReceive+1a9
…
3)设置我们的服务为“手动”,手动启动它( - 登录到服务器或重新启动后立即从不同的服务器远程启动它)后OK - 没有挂起。
4)我们删除了我们的服务(从注册表中!),并将一个批处理文件放在windows“startup”文件夹中。此批处理文件调用服务的代码,但将其作为普通的C#可执行文件运行。服务器重启后,它也挂在同一个有问题的代码行上(再次......直到我们杀死它为止2天)。
5)使用ADSI(System.DirectoryServices)而不是WMI具有相同的结果(启动应用程序池被挂起!)。
我们一直在挖掘到这过去2周...
我的问题:
==========
1)有没有人遇到同样的问题?
2)有谁知道它为什么挂起?我们应该考虑是否还有其他服务依赖性?
3)有没有人有这个问题的解决方案?
4)为什么只有在服务设置为“自动”启动后才会重新启动?如果我们手动执行 - 一切正常!
*****小更新:**
我们注意到,在虚拟机(VMware的站)重新启动后服务挂起,平均40分钟〜的,直到它开始(注:它永远不会失败开始,但40分钟太多了)。事件日志消息记录在系统事件日志中,表明我们的服务挂起超过16分钟(来源:Service Control Manager,事件ID:7044)。
在“普通”机器(真正的金属)上,服务开始前的平均时间为〜55小时!再次,如上所述记录事件日志条目。
avergae值是从8个不同的“真实”服务器计算的。
我看到没有人回答,但我会发布一些新闻反正...
我们已经发现了,在此之前启动应用程序池,设置服务状态为“已启动”,并打开运行上述代码的新线程(new Thread(...)
)(使用WMI启动应用程序池)解决了此问题。
这是OnStart
方法的服务的伪代码:
OnStart {
StopProcedure();
InvokeInitXServer1And2(); //COM-Exe servers
InvokeInitCOMPlusApplication(); //dllhost.exe
SetServiceStatus(SERVICE_STARTED);
Thread worker = new Thread(new threadStart(IISAppPoolStartWMI); //Calls the code
}
这是服务在合理的时间开始的唯一方式(最大的3分钟,〜实际机器的1.5分钟平均和虚拟机都是!),并启动w3wp.exe进程。
如果有人对它进行了探索(MTA \ STA问题?!?!?),我很乐意阅读它。