WMI를 사용하여 IIS 7에서 작업자 프로세스 및 AppDomain 관리

작성자: Tim Ammann

WMI 스크립팅을 사용하면 IIS에서 작업자 프로세스 및 애플리케이션 도메인(AppDomains)을 비교적 쉽게 관리할 수 있습니다. IIS 작업자 프로세스는 WAS(Windows Process Activation Service)에 의해 생성되고 W3wp.exe 의해 실행됩니다. 작업자 프로세스에는 일반적으로 .aspx 페이지에 대한 요청에 대한 응답으로 생성되는 AppDomain이 포함될 수 있습니다.

이 문서에서는 몇 줄의 VBScript를 사용하여 다음 작업을 수행하는 방법을 설명합니다.

  • 작업자 프로세스에 대해 현재 실행 중인 요청 보기
  • 모든 작업자 프로세스의 상태 가져오기
  • 특정 AppDomain 또는 모든 AppDomains 언로드
  • 모든 AppDomain 및 해당 속성 표시

첫 번째 단계

  1. IIS 및 스크립팅이 사용하도록 설정되어 있는지 확인합니다.

    a. Windows Vista를 사용하는 경우 제어판, 프로그램 및 기능을 연 다음 Windows 기능을 엽니다. "웹 관리 도구"에서 "IIS 관리 스크립트 및 도구"를 선택하여 스크립팅을 사용하도록 설정합니다. b. Windows Server® 2008을 사용하는 경우 서버 관리자 엽니다. 역할 추가 마법사를 사용하여 IIS 웹 서버를 설치합니다. 역할 서비스 선택 페이지의 관리 도구 섹션에서 "IIS 관리 스크립트 및 도구"를 선택합니다.

  2. 관리자 권한으로 명령을 실행합니다. 권한이 상승된 명령 프롬프트 창을 열려면 시작을 클릭하고 모든 프로그램을 가리킨 다음 보조프로그램을 클릭합니다. 그런 다음 명령 프롬프트를 마우스 오른쪽 단추로 클릭하고 관리자 권한으로 실행을 클릭합니다. 관리자 권한으로 명령 셸을 열면 해당 명령 셸에서 실행하는 모든 애플리케이션이 관리자 권한으로 실행됩니다.

  3. .vbs 확장자를 사용하여 스크립트 파일을 텍스트 형식으로 저장합니다. "cscript.exe <scriptname.vbs>" 구문을 사용하여 명령 프롬프트에서 실행할 수 있습니다.

  4. 시작하기 전에 AppCmd 도구를 사용하여 System32\inetsrv\config\applicationhost.config 파일을 백업합니다. 백업 복사본을 사용하면 나중에 원본 버전을 복사하여 IIS를 원래 상태로 복원할 수 있습니다. 백업을 수행하려면 다음 단계를 수행합니다.

    a. 관리자 권한 명령 프롬프트 창을 엽니다.
    b. c.Type appcmd add backupName을 입력 cd %Windir%\system32\inetsrv\ 하여 ApplicationHost.config 파일을 백업합니다. 여기서 backupName은 백업에 대해 지정한 이름입니다. 지정한 백업 이름이 있는 디렉터리가 디렉터리 아래에 %Windir%\system32\inetsrv\backup 만들어집니다. 이름을 지정하지 않으면 appcmd는 현재 날짜와 시간을 사용하여 디렉터리 이름을 자동으로 생성합니다.

작업자 프로세스

이 섹션에서는 웹 서버의 각 작업자 프로세스에 대해 현재 실행 중인 요청을 검색하는 방법을 보여 줍니다. 그런 다음 각 작업자 프로세스 PID, 상태 및 해당 프로세스가 속한 애플리케이션 풀을 표시하는 방법을 알아봅니다.

실행 요청 가져오기

IIS의 흥미로운 새로운 기능 중 하나는 작업자 프로세스에서 현재 실행 중인 요청을 볼 수 있는 기능입니다. WorkerProcess.GetExecutingRequests 메서드를 사용하여 이 작업을 수행할 수 있습니다.

WorkerProcess.GetExecutingRequests 메서드는 메서드가 실행되었을 때 실행된 요청을 스냅샷 방식으로 보고합니다. 대부분의 요청은 매우 빠르게 실행되므로 웹 브라우저에서 메서드를 수동으로 테스트하기가 쉽지 않을 수 있습니다. 이러한 이유로 이 목적을 위해 웹 페이지를 만듭니다.

메모장을 사용하여 다음 텍스트를 텍스트 파일에 넣습니다. 그런 다음 Sleep.aspx라는 이름을 사용하여 파일을 저장합니다.

<%  System.Threading.Thread.Sleep(30000)
Response.Write ("I'm finally finished...") %>

기본 웹 사이트의 %systemdrive%\inetpub\wwwroot콘텐츠 디렉터리에 Sleep.aspx 파일을 배치합니다.

만든 Sleep.aspx 파일은 웹 페이지에 대한 요청을 실행하는 데 30초가 걸립니다. 이렇게 하면 GetExecutingRequests가 작동하는 스크립트를 실행할 수 있습니다.

GetExecutingRequests 메서드는 빈 배열 변수를 OUT 매개 변수로 사용하여 HttpRequest 개체로 채웁니다. 이러한 요청을 반복하여 각 요청에 대한 특성을 표시할 수 있습니다. 다음 스크립트는 HttpRequest 개체 출력을 사용하고 각 요청에 대한 현재 모듈, 동사, 호스트 이름 및 URL을 표시합니다.

다음 스크립트를 메모장에 복사하고 파일 이름 GetRequests.vbs 저장합니다.

Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oWorkerProcesses = oWebAdmin.InstancesOf("WorkerProcess")
     
For Each oWorkerProcess In oWorkerProcesses
    ' Place the requests queued for a process into an array variable.
    oWorkerProcess.GetExecutingRequests arrReqs
    
    ' Show the number of requests queued.
    If IsNull(arrReqs) Then
        WScript.Echo "No currently executing requests."

    Else
        ' Display the number of requests.
        WScript.Echo "Number of currently executing requests: " & _
            UBound(arrReqs) + 1
        WScript.Echo
  
        ' List the properties of each request.
        For Each oRequest In arrReqs
            WScript.Echo "Module: " & "[" & oRequest.CurrentModule & "]"
            WScript.Echo "Verb:" & "[" & oRequest.Verb & "]"
            WScript.Echo "HostName: " & "[" & oRequest.HostName & "]"
            WScript.Echo "Url: " & "[" & oRequest.Url & "]"
            WScript.Echo
        Next
    End If
Next

관리자 권한 명령 프롬프트 창을 열고 GetRequests.vbs 파일을 저장한 디렉터리로 이동합니다.

스크립트를 실행하기 전에 웹 브라우저의 주소 표시줄에 를 입력 http://localhost/sleep.aspx 합니다. 그러면 요청 실행이 시작되고 Sleep.aspx 페이지 렌더링을 기다리는 동안 브라우저가 30초 동안 회전하도록 설정됩니다.

브라우저가 페이지를 렌더링하기 위해 대기하는 동안 방금 연 명령 프롬프트 창에 다음을 입력하여 스크립트를 실행합니다.

Cscript.exe GetRequests.vbs

샘플 출력

표시되는 출력은 다음과 유사합니다.

Number of currently executing requests: 2
Module: [ManagedPipelineHandler]
Verb:[GET]
HostName: [localhost]
Url: [/MyApp/]
Module: [ManagedPipelineHandler]
Verb:[GET]
HostName: [localhost]
Url: [/MyApp/default.aspx]

작업자 프로세스의 상태 가져오기

IIS WMI 공급자의 WorkerProcess 개체에는 작업자 프로세스가 시작, 실행 또는 중지 중인지 여부를 나타내는 GetState 메서드가 있습니다. 또한 WorkerProcess에는 ApplicationPool 및 PID라는 두 가지 속성이 있습니다. ApplicationPool 속성은 작업자 프로세스가 속한 애플리케이션 풀을 나타냅니다. PID 속성에는 작업자 프로세스를 고유하게 식별하는 프로세스 ID가 포함됩니다.

다음 코드를 사용하여 각 작업자 프로세스 PID 및 상태와 해당 애플리케이션 풀을 나열할 수 있습니다. 실행 중인 작업자 프로세스가 없으면 스크립트가 자동으로 종료됩니다. 코드를 메모장에 복사하고 파일 이름 GetState.vbs 저장합니다.

' Connect to the WMI WebAdministration namespace. 
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration") 
       
' Get the worker process instances. 
Set oWorkerProcesses = oWebAdmin.InstancesOf("WorkerProcess") 
       
' Get the ID of each worker process in the application pool and report its status. 
For Each oWorkerProcess In oWorkerProcesses 
       
    ' Report the worker process state via the GetStateDescription helper function. 
    WScript.Echo "WorkerProcess " & oWorkerProcess.ProcessID & ": " & _ 
        GetStateDescription(oWorkerProcess.GetState) 
    WScript.Echo "Application Pool: " & oWorkerProcess.AppPoolName
    WScript.Echo 
Next 

' The helper function translates the return value into text. 
Function GetStateDescription(StateCode) 
    Select Case StateCode 
        Case 0 
            GetStateDescription = "Starting" 
        Case 1 
            GetStateDescription = "Running" 
        Case 2 
            GetStateDescription = "Stopping" 
        Case 3 
            GetStateDescription = "Unknown" 
       
        Case Else 
            GetStateDescription = "Undefined value." 
    End Select 
End Function

관리자 권한 명령 프롬프트 창을 열고 GetState.vbs 파일을 저장한 디렉터리로 이동합니다. 방금 연 명령 프롬프트 창에 다음을 입력하여 스크립트를 실행합니다.

Cscript.exe GetState.vbs

샘플 출력

출력은 다음과 유사합니다.

WorkerProcess 1336: Running 
Application Pool: DefaultAppPool 
       
WorkerProcess 3680: Running 
Application Pool: Classic .NET AppPool 
       
WorkerProcess 1960: Running 
Application Pool: NewAppPool

이제 WMI 스크립팅을 사용하여 작업자 프로세스의 비밀을 표시하는 방법을 배웠으므로 애플리케이션 도메인에도 동일한 작업을 수행합니다.

AppDomain

ASP.NET 페이지에 대한 요청이 처음 수신되면 IIS 관리 엔진 모듈은 메모리에 애플리케이션 도메인(AppDomain)을 만듭니다. AppDomain은 aspx 페이지 또는 관리 코드를 사용하는 모든 페이지에 대한 요청을 처리합니다. WMI를 사용하여 AppDomains를 언로드하고 열거하는 것은 간단합니다. 이 섹션에서는 두 가지 작업을 모두 수행하는 방법을 보여 줍니다.

특정 AppDomain 언로드

IIS 7 이상에서 AppDomain 언로드가 IIS 6.0과 약간 다르게 작동합니다. IIS 6.0 AppUnload 명령은 out-of-process ASP 애플리케이션을 언로드한 반면, IIS 7 이상 AppDomain.Unload 메서드는 ASP.NET 애플리케이션 도메인만 언로드합니다. 지원되는 IIS 5.0 호환성 모드가 IIS 7 이상에 더 이상 존재하지 않으므로 AppUnload 기능이 사라졌습니다.

특정 AppDomain을 언로드하려면 고유하게 식별할 수 있어야 합니다. AppDomain 개체에는 ApplicationPath, ID 및 SiteName의 세 가지 주요 속성이 있습니다. 그러나 이러한 항목 중 하나만 사용자의 용도로 충분할 수 있습니다.

덧붙여 AppDomain ID 속성은 숫자가 아니라 다음과 같은 경로입니다.

/LM/W3SVC/1/ROOT

나열된 경로의 "1"은 사이트 ID입니다(기본적으로 1은 기본 웹 사이트에 해당). 서버의 AppDomains 및 해당 속성 목록을 먼저 생성해야 하는 경우 이 문서의 뒷부분에 있는 "AppDomains 열거" 섹션을 참조하세요.

다음 스크립트는 "Northwind"라는 AppDomain을 언로드합니다. 스크립트는 일치하는 ApplicationPath가 있는 AppDomains를 검색할 때까지 사용 가능한 AppDomains를 반복합니다. 코드를 메모장에 복사하고 "Northwind"를 선택한 AppDomain 애플리케이션 경로로 바꾸고 AppDomainUnload.vbs 이름으로 파일을 저장합니다.

관리자 권한 명령 프롬프트 창을 열고 AppDomainUnload.vbs 파일을 저장한 디렉터리로 이동합니다. 방금 연 명령 프롬프트 창에 다음을 입력하여 스크립트를 실행합니다.

Cscript.exe AppDomainUnload.vbs
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oAppDomains = oWebAdmin.ExecQuery("SELECT * FROM AppDomain")

' Unload only the Northwind application domain.
For Each oAppDomain In oAppDomains
    If oAppDomain.ApplicationPath = "/Northwind/" Then 
        oAppDomain.Unload
        Exit For 
    End If 
Next

모든 AppDomain 언로드

서버에서 모든 AppDomain을 언로드하는 것이 더 쉽습니다. 단순히 검색하고, 반복하고, 각각 차례로 언로드합니다.

다음 예제에서는 IIS 웹 서버의 모든 애플리케이션 도메인을 언로드합니다. 간단한 WQL 쿼리(WQL은 WMI의 SQL 버전임)를 사용하여 AppDomains를 검색하는 방법을 확인합니다.

코드를 메모장에 복사하고 이름이 AppDomainUnloadAll.vbs 파일을 저장합니다. 관리자 권한 명령 프롬프트 창을 열고 AppDomainUnloadAll.vbs 파일을 저장한 디렉터리로 이동합니다. 방금 연 명령 프롬프트 창에 다음을 입력하여 스크립트를 실행합니다.

Cscript.exe AppDomainUnloadAll.vbs
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")

' Get all the application domains on the Web server.
Set oAppDomains = oWebAdmin.ExecQuery("SELECT * FROM AppDomain")

' Unload all the application domains.
For Each oAppDomain In oAppDomains
    oAppDomain.Unload
Next

WQL 쿼리 구문 대신 이전에 WorkerProcess에서 했던 것처럼 WMI InstancesOf 메서드를 사용할 수 있습니다.

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

AppDomains 열거

이전 스크립트와 유사한 접근 방식을 사용하여 현재 실행 중인 AppDomains 및 해당 속성을 모두 표시할 수 있습니다. 다음은 AppDomain 속성 목록입니다.

  • ApplicationPath
  • Id
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

다음 스크립트는 물리적 경로 속성을 제외한 각 AppDomain에 대한 모든 속성을 보여 주지만 이 속성을 쉽게 추가할 수 있습니다. 편의를 위해 스크립트는 키와 런타임 속성을 별도로 표시합니다.

코드를 메모장에 복사하고 AppDomainProps.vbs 이름으로 파일을 저장합니다. 관리자 권한 명령 프롬프트 창을 열고 AppDomainProps.vbs 파일을 저장한 디렉터리로 이동합니다. 방금 연 명령 프롬프트 창에 다음을 입력하여 스크립트를 실행합니다.

Cscript.exe AppDomainProps.vbs
'Connect to the WMI WebAdministration namespace
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")
WScript.Echo "AppDomain Count: " & oAppDomains.Count
WScript.Echo 
ADCounter = 0
For Each oAppDomain In oAppDomains
    ADCounter = ADCounter + 1
    WScript.Echo "---- AppDomain " & ADCounter & " of " & _
                oAppDomains.Count & " ----" & vbCrLf
    WScript.Echo "[ Key properties ]"
    WScript.Echo "ID: " & oAppDomain.ID
    WScript.Echo "Site Name: " & oAppDomain.SiteName
    WScript.Echo "Application Path: " & oAppDomain.ApplicationPath
    WScript.Echo
    WScript.Echo "[ Run-time properties ]"
    WScript.Echo "Process ID: " & oAppDomain.ProcessID
    WScript.Echo "Is idle: " & oAppDomain.IsIdle
    WScript.Echo vbCrLf
Next

샘플 출력

출력은 다음과 같습니다.

AppDomain Count: 3
---- AppDomain 1 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/1/ROOT
Site Name: Default Web Site
Application Path: /

[ Run-time properties ]
Process ID: 3608
Is idle: False

---- AppDomain 2 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/2/ROOT/ContosoApp
Site Name: ContosoSite
Application Path: /ContosoApp/

[ Run-time properties ]
Process ID: 3608
Is idle: True

---- AppDomain 3 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/1/ROOT/Fabrikam
Site Name: Default Web Site
Application Path: /Fabrikam/

[ Run-time properties ]
Process ID: 2552
Is idle: False

결론

이 문서에서는 IIS 작업자 프로세스 및 AppDomains에 대한 정보를 검색하기 위한 몇 가지 기본 WMI 스크립팅 기술을 보여 줍니다. WMI InstanceOf 메서드 및 WQL 쿼리를 사용하여 검색했습니다. 다음은 제시된 작업 및 사용된 메서드에 대한 간략한 검토입니다.

  • 작업자 프로세스에 대해 현재 실행 중인 요청 보기: WorkerProcess.GetExecutingRequests
  • 모든 작업자 프로세스의 상태 가져오기: WorkerProcess.GetState
  • 특정 AppDomain 또는 모든 AppDomains 언 로드: AppDomain.Unload