2009-11-20 2 views
0

WMI 또는 ADSI를 사용하여 Windows 서비스 (C#으로 작성, "자동"시작)로 응용 프로그램 풀을 시작하는 이상한 상황이 발생했습니다 서버가 재부팅됩니다.재부팅 후 바로 WMI ADSI (C#)가있는 응용 프로그램 풀 시작이 중단됨

나는이 문제에 대해 설명합니다

: 우리는 많은 응용 프로그램을 개발하고있다

(윈도우 2003 서버 SP2를, 6.0 IIS) 다음과 같은 주요 프로세스를 포함 (이러한 프로세스는 Windows 서비스 시작 절차 때를 사용하여 초기화 & 호출 응용 프로그램이 시작됩니다.

1) XServer1.exe, XServer2.exe - 이러한 프로세스는 일부 논리를 포함하지만 주로 DCOM (주로 .NET2COM interOp 호출 &)을 통해 COM 개체를 다른 프로세스에 제공합니다 순수한 COM 호출). 예를 들어, 일부 고전적인 "응용 프로그램 범위 정적 개체"(w3wp.exe)는 이러한 프로세스 내부에서 "작동"하는 COM 개체입니다.

2) dllhost.exe - 이것은 COM + 응용 프로그램입니다. 일부 DLL은 "상태 서버"(ASP.NET out-of-proc 세션 서버와 동일한 개념이지만 고전적인 ASP 페이지의 경우) 역할을하는이 프로세스에로드됩니다.

3) 우리의 ASP 페이지, ASP.NET 페이지, WCF 서비스 등등의 3 가지 IIS 응용 프로그램 풀 (우리는 appPool1 \ 2 \ 3이라고 부릅니다.) - 코드 (native C++ COM dlls & C#) 응용 프로그램 풀 (w3wp.exe)은 일반적으로 (1) & (2)에 설명 된 프로세스에 대한 DCOM 호출을 수행합니다. appPool1 만 웹 가든으로 구성 할 수 있습니다.

우리의 응용 프로그램을 시작 \ 중지하려면이 절차를 제어하는 ​​Windows 서비스 (C#)를 작성했습니다. 서비스 프로세스는 XWinService.exe입니다. 이 서비스는 (지속적인 시도는이 같은 목록을 만들어 목록은 처음 4 개 서비스를 시작했다 ...) 다음과 같은 Windows 서비스에 따라 달라집니다

W3SVC에게

aspnet_state

COMSysApp

DCOMLAUNCH을

012에 lanmanserver

에서 winmgmt 3,516,

는 한 lanmanworkstation

seclogon

브라우저

TermService

는 (서비스 구현) 응용 프로그램의 중지 절차의 요약 :

1) 3 IIS 응용 프로그램 풀을 중지 (appPool1 \ 2 \ 3) - 응용 프로그램이 종료 될 때 w3wp.exe 프로세스가 실행되지 않도록하기 위해 수행됩니다. 이것은 C#을 (system.Management.dll)

2) 정지 XServer1 \의 2.exe

3) COM + 응용 프로그램 (에서 Dllhost.exe 중지)에서 WMI로 구현됩니다.

(서비스 구현) 응용 프로그램의 시작 프로 시저의 요약 :

1)은 중지 프로 시저를 실행 - 이것은이 시간 외에는 HTTP 히트가 W3wp.exe를 프로세스를 깨워 없다는 것을 보장합니다.

2) &을 호출합니다. XServer1 \ 2.exe COM-Exe 서버를 초기화합니다. w3wp.exe를 호출하기 전에 초기화가 필요합니다. 일부 개체가 초기화 된 후에야 w3wp.exe가이 서버에 액세스 할 수 있습니다. 이것은 .NET2COM InterOp (결국 DCOM)에 의해 구현됩니다.

3) &은 dllhost.exe (COM + 응용 프로그램) 프로세스를 초기화합니다.이 프로세스는 ComAdmin Catalog 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)이 "hang"동안 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 
…. 

다음 서비스, Svchost.exe에서이다 과정 (884)의 구성 요소 (DCOM을 통해)를 호출 실행이 스레드 : AeLookupSvc, AudioSrv, 브라우저, CryptSvc을 , dmserver, EventSystem, helpvc, lanmanserver, lanmanworkstation, 스케줄, seclogon, SENS, ShellHWDetection, TrkWks, winmgmt, wuauserv, WZCSVC.

"winmgmt"서비스 (WMI 책임자)가이 프로세스에서 실행 중이며 서비스가 이에 따라 달라 지므로 winmgmt가 시작된 후 서비스가 시작됩니다 (IIS W3SVC 서비스의 경우도 마찬가지 임).

svchost.exe 프로세스 (884)가 덤프되었으며 프로세스 2880에 액세스하는 스레드 (DCOM 호출이 끝날 때까지 대기 중임)를 볼 수 있습니다.이 스레드는 - wmiprvse.exe입니다 (WMI 서버라고 생각합니다. 관련성이 있는지 알지만이 프로세스는 2 가지 사례가 있습니다.) 이것은 스레드의 기본 호출 스택입니다 (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) 레지스트리에서 우리 서비스를 삭제하고 윈도우 "startup"폴더에 배치 파일을 저장했습니다. 이 배치 파일은 서비스의 코드를 호출하지만 일반적인 C# 실행 파일로 실행합니다. 서버를 재부팅 한 후에도 동일한 문제가있는 코드 행에 멈 춥니 다 (다시 ... 죽일 때까지 2 일 동안).

5) WMI 대신 ADSI (System.DirectoryServices)를 사용하면 응용 프로그램 풀이 정지되는 것과 같은 결과가 나타납니다.

우리는 지난 2 주간이 파고되었습니다 ...

내 질문 :

1) 사람이 같은 발생 했

========== 발행물?

2) 왜 사람이 응답하는지 알고 있습니까? 우리가 염두에 두어야 할 추가적인 서비스 의존성이 있습니까?

3) 누구든지이 문제에 대한 해결책이 있습니까?

4) 서비스가 "자동"으로 시작되도록 설정 한 경우에만 재부팅 후 왜 이런 현상이 발생합니까? 수동으로 처리하면 모든 것이 정상입니다! 그것은 결코 실패하지 않는다 :

***** 작은 업데이트 : VM을 (VM웨어 스테이션)가 시작할 때까지 서비스가, ~ 40 분의 평균 재부팅 후 중단 (노트에 **는

우리는 그것을 발견했습니다 시작하지만 40 분이 너무 길다). 이벤트 로그 메시지가 시스템 이벤트 로그에 기록되어 서비스가 16 분 이상 중지되었음을 나타냅니다 (원본 : Service Control Manager, 이벤트 ID : 7044).

"일반"기계 (실제 금속)에서 서비스가 시작될 때까지 평균 시간은 ~ 55 시간입니다 !!! 다시, 이벤트 로그 항목은 위에서 설명한대로 기록됩니다.

avergae 값은 10 개의 differens VMs & 개의 8 개의 "실제"서버에서 계산되었습니다. 우리가 발견 한

, 서비스 상태를 설정, 응용 프로그램 풀을 시작하기 그 이전에 "시작"과를 열기 위해 ...

답변

0

나는 아무도 응답 없었다 볼 수 있지만 어쨌든 소식을 게시합니다 위의 코드를 실행하는 새 스레드 (new Thread(...)) (WMI로 응용 프로그램 풀 시작)는이 문제를 해결합니다.

는 서비스의 OnStart 방법의 의사 코드입니다 : 실제 기계의 1.5 분 ~의

OnStart { 
    StopProcedure(); 

    InvokeInitXServer1And2(); //COM-Exe servers 

    InvokeInitCOMPlusApplication(); //dllhost.exe 

    SetServiceStatus(SERVICE_STARTED); 

    Thread worker = new Thread(new threadStart(IISAppPoolStartWMI); //Calls the code 
} 

이 서비스가 적절한 시간에 시작하는 유일한 방법입니다 (최대 3 분의 평균 및 VM 모두!) 및 w3wp.exe 프로세스가 시작되었습니다.

누구든지 MTA \ STA 문제 (?!?!)가 있으면 읽을 수 있습니다.