2009-11-20 26 views
0

我遇到了一种奇怪的情况,那就是在使用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个不同的“真实”服务器计算的。

回答

0

我看到没有人回答,但我会发布一些新闻反正...

我们已经发现了,在此之前启动应用程序池,设置服务状态为“已启动”,并打开运行上述代码的新线程(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问题?!?!?),我很乐意阅读它。

相关问题