다음을 통해 공유


애플리케이션 풀 <cpu에 대한 CPU 설정>

개요

<cpu> 컬렉션에 있는 요소의 <add> 요소는 애플리케이션 풀에서 <applicationPools> 사용할 CPU 사용 매개 변수 및 CPU 작업에 대한 값을 구성합니다.

NUMA 지원

NUMA(Non-Uniform Memory Access)는 프로세서를 자체 전용 메모리에 연결하기 위한 하드웨어 기반 방법입니다. NUMA는 다중 프로세서 지원을 위한 기존 SMP(대칭 다중 프로세서) 모델의 대안으로 프로세서 속도를 높이는 데 사용됩니다. NUMA에서 프로세스를 배포하고 선호하도록 IIS 8 이상을 설정할 수 있습니다. NUMA 사용은 IIS 작업자 프로세스가 시작될 때 IIS가 가장 최적의 NUMA 노드를 식별할 수 있도록 하는 numaNodeAssignment 특성과 IIS 작업자 프로세스의 스레드가 NUMA 노드에 선호되는 방식을 결정하는 numaNodeAffinityMode 특성에 의해 CPU 요소에 구성됩니다. 또한 NUMA는 processModel 요소의 MaxProcesses 특성을 사용하여 구성됩니다. 로 설정 0 하면 IIS가 NUMA 노드와 동일한 수의 작업자 프로세스를 자동으로 실행하도록 지정합니다. 자세한 내용은 NUMA 하드웨어에서 IIS 8.0 멀티코어 크기 조정을 참조하세요.

NUMA 선택 논리 및 선호도 유형은 IIS가 NUMA 하드웨어에서 실행되는 경우에만 고급 설정 대화 상자에서 설정할 수 있습니다.

호환성

버전 참고
IIS 10.0 <cpu> 요소가 IIS 10.0에서 수정되지 않았습니다.
IIS 8.5 <cpu> 요소가 IIS 8.5에서 수정되지 않았습니다.
IIS 8.0 제한 동작을 정의하기 위해 특성에 action 두 개의 열거형 값이 추가되었습니다. processorGroup 사용된 프로세서 그룹의 수를 정의하기 위해 특성이 추가되었습니다. numaNodeAssignmentnumaNodeAffinityMode 특성이 추가되어 NUMA 노드의 동작을 지정했습니다.
IIS 7.5 <cpu> 요소가 IIS 7.5에서 수정되지 않았습니다.
IIS 7.0 요소는 <cpu> IIS 7.0에서 도입되었습니다.
IIS 6.0 요소는 <cpu> IIS 6.0 IIsApplicationPools 메타베이스 속성의 일부를 대체합니다.

설치 프로그램

컬렉션은 <applicationPools> IIS 7 이상의 기본 설치에 포함되어 있습니다.

방법

CPU 구성 설정을 편집하는 방법

  1. IIS(인터넷 정보 서비스) 관리자를 엽니다.

    • Windows Server 2012 또는 Windows Server 2012 R2를 사용하는 경우:

      • 작업 표시줄에서 서버 관리자 클릭하고 도구를 클릭한 다음 IIS(인터넷 정보 서비스) 관리자를 클릭합니다.
    • Windows 8 또는 Windows 8.1 사용하는 경우:

      • Windows 키를 누른 채로 문자 X를 누른 다음 제어판 클릭합니다.
      • 관리 도구를 클릭한 다음 IIS(인터넷 정보 서비스) 관리자를 두 번 클릭합니다.
    • Windows Server 2008 또는 Windows Server 2008 R2를 사용하는 경우:

      • 작업 표시줄에서 시작을 클릭하고 관리 도구를 가리킨 다음 IIS(인터넷 정보 서비스) 관리자를 클릭합니다.
    • Windows Vista 또는 Windows 7을 사용하는 경우:

      • 작업 표시줄에서 시작을 클릭한 다음 제어판 클릭합니다.
      • 관리 도구를 두 번 클릭한 다음 IIS(인터넷 정보 서비스) 관리자를 두 번 클릭합니다.
  2. 연결 창에서 서버 이름을 확장하고 애플리케이션 풀을 클릭한 다음 편집할 애플리케이션 풀을 클릭합니다.
    연결 창에서 채우는 애플리케이션 풀 화면의 스크린샷.

  3. 작업 창에서 고급 설정...을 클릭합니다.

  4. 고급 설정 대화 상자에서 편집할 CPU 속성을 클릭한 다음 대화 상자의 속성 값 섹션에서 값을 편집한 다음 확인을 클릭합니다. 예를 들어 제한 작업을NoAction, KillW3wp, Throttle 또는 ThrottleUnderLoad 변경할 수 있습니다.
    고급 설정 대화 상자의 로드 아래 제한 섹션의 스크린샷.

NUMA(Non-Uniform Memory Access) 하드웨어에서 사용하도록 IIS를 구성하는 방법

  1. 작업 표시줄에서 서버 관리자 클릭하고 도구를 클릭한 다음 IIS(인터넷 정보 서비스) 관리자를 클릭합니다.

  2. 연결 창에서 서버 이름을 확장한 다음 애플리케이션 풀을 클릭합니다.

  3. 애플리케이션 풀 창에서 NUMA에 대해 구성하려는 풀을 선택합니다.

  4. 작업 창에서 고급 설정을 선택합니다.

  5. 프로세스 모델에서 최대 작업자 프로세스를0설정합니다.

    최대 작업자 프로세스 필드가 0으로 설정된 프로세스 모델 섹션의 스크린샷

  6. CPU에서 processorGroup, numaNodeAffinityModenumaNodeAssignment를 설정합니다.

  7. 확인을 클릭합니다.

구성

특성

attribute Description
action 선택적 열거형 특성입니다. 작업자 프로세스가 구성된 CPU 제한을 초과할 때 IIS가 수행하는 작업을 구성합니다. 작업 특성은 애플리케이션별 풀 기준으로 구성됩니다.

작업 특성은 다음과 같은 가능한 값 중 하나일 수 있습니다. 기본값은 NoAction입니다.

Description
NoAction CPU 제한을 초과하면 아무 작업도 수행되지 않습니다. 이벤트 로그에 경고가 기록됩니다.

숫자 값은 입니다 0.

KillW3wp CPU 제한을 초과하는 애플리케이션 풀 작업자 프로세스는 강제로 종료됩니다.

숫자 값은 입니다 1.

Throttle CPU 사용량은 제한에 설정된 값으로 제한됩니다. 제한 간격은 사용되지 않으며 이벤트 로그 항목이 생성됩니다.

숫자 값은 입니다 2.

ThrottleUnderLoad CPU 사용량은 CPU에 경합이 있는 경우에만 제한됩니다. 제한 간격은 사용되지 않으며 이벤트 로그 항목이 생성됩니다.

숫자 값은 입니다 3.

limit 선택적 uint 특성입니다. resetInterval 특성에 표시된 대로 애플리케이션 풀에서 작업자가 일정 기간 동안 사용할 수 있는 CPU 시간의 최대 백분율(1%의 1/1000분의 1)을 구성합니다. 제한 특성으로 설정된 제한을 초과하면 이벤트가 이벤트 로그에 기록되고 선택적 이벤트 집합이 트리거될 수 있습니다. 이러한 선택적 이벤트는 작업 특성에 의해 결정됩니다.

참고: IIS 8.5 이상에서는 IIS 관리자의 CPU 창에서 제한을 백분율로 설정합니다. IIS 8.0에서 IIS 관리자의 CPU 창에서 제한을 1%의 1/1000으로 설정합니다. 두 경우 limit 모두 applicationHost.config 특성은 1%의 1/1000에 있습니다.

기본값은 CPU 제한을 사용하지 않도록 설정하는 입니다 0.
numaNodeAffinityMode 선택적 열거형 특성입니다. NUMA 노드에 선호되는 프로세스의 스레드가 노드의 코어에서 예약되는 방법을 지정합니다.

numaNodeAffinityMode 특성은 다음과 같은 가능한 값 중 하나일 수 있습니다. 기본값은 Soft입니다.

Description
Soft 프로세스가 선호되는 NUMA 노드의 코어를 사용할 수 있는 한 프로세스의 모든 스레드가 해당 코어에서 예약됩니다. 그러나 스케줄러가 선호도가 지정된 노드의 코어에서 프로세스를 예약할 수 없는 경우 다른 NUMA 노드의 코어에서 프로세스를 예약할 수 있습니다.

숫자 값은 입니다 0.

Hard NUMA 노드에 선호되는 프로세스의 모든 스레드는 노드의 코어와 해당 코어에서만 예약됩니다. 해당 프로세스의 스레드는 다른 NUMA 노드의 코어에서 예약되지 않습니다.

숫자 값은 입니다 1.

numaNodeAssignment 선택적 열거형 특성입니다. IIS가 프로세스를 선호할 NUMA(비균일 메모리 액세스) 노드를 결정하는 방법을 지정합니다. NUMA 노드에는 단일 메모리 뱅크를 공유하는 코어 클러스터가 포함되어 있습니다. 이 특성은 NUMA 노드를 사용할 수 있는 경우에만 CPU 고급 설정에서 사용할 수 있습니다.

numaNodeAssignment 특성은 다음과 같은 가능한 값 중 하나일 수 있습니다. 기본값은 Most Available Memory입니다.

Description
Most Available Memory 프로세스가 메모리가 가장 많은 NUMA 노드에 할당됩니다.

숫자 값은 입니다 0.

Windows Scheduling Windows 일정은 프로세스가 할당된 NUMA 노드를 결정합니다.

숫자 값은 입니다 1.

processorGroup 선택적 int 특성입니다. 사용된 프로세서 그룹 수(0부터 시작)입니다. 프로세서 그룹에는 여러 코어가 포함됩니다. 프로세서 그룹 특성은 서버에 여러 프로세서 그룹이 있는 경우에만 CPU 고급 설정에서 사용할 수 있습니다.

기본값은 입니다 0. 즉, 단일 프로세서 그룹이 사용됩니다.
resetInterval 선택적 timeSpan 특성입니다. 애플리케이션 풀의 CPU 모니터링 및 제한 제한에 대한 초기화 기간(분)을 지정합니다. 마지막 프로세스 회계 재설정 이후 경과된 시간(분)이 이 속성에 지정된 수와 같으면 IIS는 로깅 및 제한 간격 모두에 대한 CPU 타이머를 다시 설정합니다.

중요: resetInterval 값은 로깅 작업 사이의 시간보다 커야 합니다. 그렇지 않으면 IIS는 로깅이 발생하기 전에 카운터를 다시 설정하고 프로세스 회계는 발생하지 않습니다.

참고: IIS의 프로세스 회계는 Windows 작업 개체를 사용하여 전체 프로세스에 대한 CPU 시간을 모니터링하기 때문에 프로세스 회계는 IIS와 별도의 프로세스에서 격리된 애플리케이션만 로그하고 제한합니다.

기본값은 00:05:00입니다.
smpAffinitized 선택적 부울 특성입니다. 애플리케이션 풀에 할당된 특정 작업자 프로세스도 지정된 CPU에 할당해야 하는지 여부를 지정합니다. 이 속성은 smpProcessorAffinityMasksmpProcessorAffinityMask2 특성과 함께 사용됩니다.

기본값은 false입니다.
smpProcessorAffinityMask 선택적 uint 특성입니다. 다중 프로세서 컴퓨터의 16진수 프로세서 마스크를 지정합니다. 이 마스크는 애플리케이션 풀에서 작업자가 처리해야 하는 CPU를 나타냅니다. 이 속성이 적용되기 전에 애플리케이션 풀에 대해 smpAffinitized 특성을 true 로 설정해야 합니다.

참고: 64비트 컴퓨터에서 smpProcessorAffinityMask 특성은 프로세서 마스크에 대한 낮은 순서의 DWORD를 포함하고 , smpProcessorAffinityMask2 특성에는 프로세서 마스크에 대한 높은 순서의 DWORD가 포함되어 있습니다. 32비트 컴퓨터에서는 smpProcessorAffinityMask2 특성이 적용되지 않습니다.

값을 1로 설정하면(이진 파일의 00000000000000001 해당) 애플리케이션 풀의 작업자 프로세스는 첫 번째 프로세서에서만 실행됩니다. 값을 2로 설정하면(이진 파일의 0000000000000010 해당) 작업자 프로세스는 두 번째 프로세서에서만 실행됩니다. 값을 3으로 설정하면(이진 파일의 0000000000000011 해당) 작업자 프로세스는 첫 번째 프로세서와 두 번째 프로세서 모두에서 실행됩니다.

참고: 이 속성을 0으로 설정하지 마세요. 이렇게 하면 대칭 SMP(다중 처리) 선호도를 사용하지 않도록 설정하고 오류 조건을 만듭니다. 즉, 한 CPU에서 실행되는 프로세스는 수명 동안 해당 CPU와 연결되지 않습니다.

기본값은 4294967295입니다.
smpProcessorAffinityMask2 선택적 uint 특성입니다. 애플리케이션 풀에서 작업자가 처리해야 하는 CPU를 나타내는 64비트 다중 프로세서 컴퓨터의 상위 DWORD 16진수 프로세서 마스크를 지정합니다. 이 속성이 적용되기 전에 애플리케이션 풀에 대해 smpAffinitized 특성을 true 로 설정해야 합니다.

참고: 64비트 컴퓨터에서 smpProcessorAffinityMask 특성은 프로세서 마스크에 대한 낮은 순서의 DWORD를 포함하고 , smpProcessorAffinityMask2 특성에는 프로세서 마스크에 대한 높은 순서의 DWORD가 포함되어 있습니다. 32비트 컴퓨터에서는 smpProcessorAffinityMask2 특성이 적용되지 않습니다.

기본값은 4294967295입니다.

자식 요소

없음

구성 샘플

다음 구성 샘플에서는 DefaultAppPool이라는 단일 애플리케이션 풀을 구성하고 CPU를 50%로 설정하고, 다시 설정 간격이 10분인 작업자 프로세스를 종료하는 작업을 수행합니다.

<applicationPools>
   <add name="DefaultAppPool">
     <cpu limit="50000" action="KillW3wp" resetInterval="00:10:00" />
   </add>
   <applicationPoolDefaults>
     <processModel identityType="NetworkService" />
   </applicationPoolDefaults>
</applicationPools>

샘플 코드

다음 코드 샘플은 CPU 제한을 초과할 때 작업자 프로세스를 종료하도록 기본 애플리케이션 풀을 구성하고 다시 설정 간격을 4분으로 구성합니다.

AppCmd.exe

appcmd.exe set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].cpu.action:"KillW3wp" /commit:apphost

appcmd.exe set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].cpu.resetInterval:"00:04:00" /commit:apphost

참고

AppCmd.exe 사용하여 이러한 설정을 구성할 때 커밋 매개 변수 apphost 를 로 설정해야 합니다. 그러면 구성 설정이 ApplicationHost.config 파일의 적절한 위치 섹션에 커밋됩니다.

C#

using System;
using System.Text;
using Microsoft.Web.Administration;

internal static class Sample
{
   private static void Main()
   {
      using (ServerManager serverManager = new ServerManager())
      {
         Configuration config = serverManager.GetApplicationHostConfiguration();
         ConfigurationSection applicationPoolsSection = config.GetSection("system.applicationHost/applicationPools");
         ConfigurationElementCollection applicationPoolsCollection = applicationPoolsSection.GetCollection();
         ConfigurationElement addElement = FindElement(applicationPoolsCollection, "add", "name", @"DefaultAppPool");

         if (addElement == null) throw new InvalidOperationException("Element not found!");

         ConfigurationElement cpuElement = addElement.GetChildElement("cpu");
         cpuElement["action"] = @"KillW3wp";
         cpuElement["resetInterval"] = TimeSpan.Parse("00:04:00");

         serverManager.CommitChanges();
      }
   }

   private static ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues)
   {
      foreach (ConfigurationElement element in collection)
      {
         if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))
         {
            bool matches = true;
            for (int i = 0; i < keyValues.Length; i += 2)
            {
               object o = element.GetAttributeValue(keyValues[i]);
               string value = null;
               if (o != null)
               {
                  value = o.ToString();
               }
               if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))
               {
                  matches = false;
                  break;
               }
            }
            if (matches)
            {
               return element;
            }
         }
      }
      return null;
   }
}

VB.NET

Imports System
Imports System.Text
Imports Microsoft.Web.Administration

Module Sample
   Sub Main()
      Dim serverManager As ServerManager = New ServerManager
      Dim config As Configuration = serverManager.GetApplicationHostConfiguration
      Dim applicationPoolsSection As ConfigurationSection = config.GetSection("system.applicationHost/applicationPools")
      Dim applicationPoolsCollection As ConfigurationElementCollection = applicationPoolsSection.GetCollection
      Dim addElement As ConfigurationElement = FindElement(applicationPoolsCollection, "add", "name", "DefaultAppPool")

      If (addElement Is Nothing) Then
         Throw New InvalidOperationException("Element not found!")
      End If

      Dim cpuElement As ConfigurationElement = addElement.GetChildElement("cpu")
      cpuElement("action") = "KillW3wp"
      cpuElement("resetInterval") = TimeSpan.Parse("00:04:00")

      serverManager.CommitChanges()
   End Sub

   Private Function FindElement(ByVal collection As ConfigurationElementCollection, ByVal elementTagName As String, ByVal ParamArray keyValues() As String) As ConfigurationElement
      For Each element As ConfigurationElement In collection
         If String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase) Then
            Dim matches As Boolean = True
            Dim i As Integer
            For i = 0 To keyValues.Length - 1 Step 2
               Dim o As Object = element.GetAttributeValue(keyValues(i))
               Dim value As String = Nothing
               If (Not (o) Is Nothing) Then
                  value = o.ToString
               End If
               If Not String.Equals(value, keyValues((i + 1)), StringComparison.OrdinalIgnoreCase) Then
                  matches = False
                  Exit For
               End If
            Next
            If matches Then
               Return element
            End If
         End If
      Next
      Return Nothing
   End Function


End Module

JavaScript

var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
var applicationPoolsSection = adminManager.GetAdminSection("system.applicationHost/applicationPools", "MACHINE/WEBROOT/APPHOST");
var applicationPoolsCollection = applicationPoolsSection.Collection;
var addElementPos = FindElement(applicationPoolsCollection, "add", ["name", "DefaultAppPool"]);

if (addElementPos == -1) throw "Element not found!";

var addElement = applicationPoolsCollection.Item(addElementPos);
var cpuElement = addElement.ChildElements.Item("cpu");
cpuElement.Properties.Item("action").Value = "KillW3wp";
cpuElement.Properties.Item("resetInterval").Value = "00:04:00";

adminManager.CommitChanges();

function FindElement(collection, elementTagName, valuesToMatch) {
   for (var i = 0; i < collection.Count; i++) {
      var element = collection.Item(i);
      if (element.Name == elementTagName) {
         var matches = true;
         for (var iVal = 0; iVal < valuesToMatch.length; iVal += 2) {
            var property = element.GetPropertyByName(valuesToMatch[iVal]);
            var value = property.Value;
            if (value != null) {
               value = value.toString();
            }
            if (value != valuesToMatch[iVal + 1]) {
               matches = false;
               break;
            }
         }
         if (matches) {
            return i;
         }
      }
   }
   return -1;
}

VBScript

Set adminManager = WScript.CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"
Set applicationPoolsSection = adminManager.GetAdminSection("system.applicationHost/applicationPools", "MACHINE/WEBROOT/APPHOST")
Set applicationPoolsCollection = applicationPoolsSection.Collection
addElementPos = FindElement(applicationPoolsCollection, "add", Array("name", "DefaultAppPool"))

If (siteElementPos = -1) Then
   WScript.Echo "Element not found!"
   WScript.Quit
End If

Set addElement = applicationPoolsCollection.Item(addElementPos)
Set cpuElement = addElement.ChildElements.Item("cpu")
cpuElement.Properties.Item("action").Value = "KillW3wp"
cpuElement.Properties.Item("resetInterval").Value = "00:04:00"

adminManager.CommitChanges()

Function FindElement(collection, elementTagName, valuesToMatch)
   For i = 0 To CInt(collection.Count) - 1
      Set element = collection.Item(i)
      If element.Name = elementTagName Then
         matches = True
         For iVal = 0 To UBound(valuesToMatch) Step 2
            Set property = element.GetPropertyByName(valuesToMatch(iVal))
            value = property.Value
            If Not IsNull(value) Then
               value = CStr(value)
            End If
            If Not value = CStr(valuesToMatch(iVal + 1)) Then
               matches = False
               Exit For
            End If
         Next
         If matches Then
            Exit For
         End If
      End If
   Next
   If matches Then
      FindElement = i
   Else
      FindElement = -1
   End If
End Function