일반 CLR 스레드에 비해 IIS 스레드가 왜 그렇게 소중합니까?
ASP의 비동기 컨트롤러에 대해 읽고 있습니다.NET MVC.
IIS 스레드가 존재하는 유일한 이유는 IIS 스레드를 저장하는 동시에 장시간 실행되는 작업을 일반 CLR 스레드에 위임하기 때문인 것 같습니다. 이는 더 저렴합니다.
몇 가지 질문이 있습니다.
- 비동기식 컨트롤러를 지원하도록 구축된 전체 아키텍처를 정당화하기 위해 IIS 스레드가 그렇게 비싼 이유는 무엇입니까?
- IIS 응용 프로그램 풀에서 실행 중인 IIS 스레드 수를 확인/구성하는 방법은 무엇입니까?
ASP.NET은 의 스레드를 사용하여 요청을 처리합니다.NET 스레드 풀입니다.스레드 풀은 스레드 초기화 비용이 이미 발생한 스레드 풀을 유지 관리합니다.따라서 이러한 스레드는 재사용이 쉽습니다..NET 스레드 풀도 자체 조정됩니다.CPU 및 기타 리소스 활용률을 모니터링하고 필요에 따라 새 스레드를 추가하거나 스레드 풀 크기를 조정합니다.일반적으로 작업을 수행하기 위해 수동으로 스레드를 만들지 않아야 합니다.대신 스레드 풀의 스레드를 사용합니다.동시에 응용 프로그램이 스레드 풀 부족 및 거부된 HTTP 요청으로 빠르게 이어질 수 있는 긴 차단 작업을 수행하지 않도록 하는 것이 중요합니다.
디스크 I/O, 웹 서비스 호출이 모두 차단됩니다.비동기 호출을 사용하여 최적화된 방법이 있습니다.비동기 호출을 하면 asp.net 에서 스레드를 해제하고 콜백 함수가 호출될 때 요청이 다른 스레드에 할당됩니다.
설정할 수 있는 스레드 수를 구성하려면 다음과 같이 하십시오.
<system.web>
<applicationPool maxConcurrentRequestsPerCPU="50" maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000"/>
</system.web>
참조: ASP.IIS 7.5, IIS 7.0 및 IIS 6.0의 NET 스레드 사용
마이크로소프트 모범 사례에서 권장하는 설정은 다음과 같습니다.
- 최대 연결을 CPU의 12 * 수로 설정합니다.이 설정은 클라이언트에서 시작할 수 있는 최대 발신 HTTP 연결 수를 제어합니다.이 경우 ASP.NET은 고객입니다.최대 연결을 CPU의 12 * 수로 설정합니다.
- maxIoThreads를 100으로 설정합니다.이 설정은 의 최대 I/O 스레드 수를 제어합니다.NET 스레드 풀입니다.이 수에는 사용 가능한 CPU 수가 자동으로 곱해집니다.maxloThreads를 100으로 설정합니다.
- maxWorkerThreads를 100으로 설정합니다.이 설정은 스레드 풀의 최대 작업자 스레드 수를 제어합니다.그런 다음 이 숫자에 사용 가능한 CPU 수를 자동으로 곱합니다.maxWorkerThreads를 100으로 설정합니다.
- minFreeThreads를 CPU 88 * 수로 설정합니다.이 설정은 스레드 풀에서 사용 가능한 스레드 수가 이 설정 값보다 낮을 경우 들어오는 모든 요청을 대기열에 넣는 데 사용됩니다.이 설정은 동시에 실행할 수 있는 요청 수를 maxWorkerThreads - minFreeThreads로 효과적으로 제한합니다.minFreeThreads를 CPU 88 * 수로 설정합니다.이렇게 하면 동시 요청 수가 12개로 제한됩니다(maxWorkerThreads가 100개라고 가정).
- minLocalRequestFreeThreads를 CPU의 76 * 수로 설정합니다.이 설정은 스레드 풀의 사용 가능한 스레드 수가 이 수보다 낮은 경우 로컬 호스트(웹 응용 프로그램이 로컬 웹 서비스로 요청을 보내는 곳)의 요청을 대기열에 넣는 데 작업자 프로세스에서 사용됩니다.이 설정은 minFreeThreads와 유사하지만 로컬 컴퓨터의 로컬 호스트 요청에만 적용됩니다.minLocalRequestFreeThreads를 CPU의 76 * 수로 설정합니다.
참고: 이 섹션에서 제공되는 권장 사항은 규칙이 아닙니다.그들은 출발점입니다.
애플리케이션에 가장 적합한 것을 찾으려면 애플리케이션을 벤치마킹해야 합니다.
IIS 스레드는 프로세서 코어 수에 따라 기본적으로 제한되는 기본 스레드 풀에서 가져옵니다.이 스레드 풀 대기열이 백업되면 IIS가 요청에 대한 응답을 중지합니다.비동기 코드를 사용하면 비동기 작업이 수행되는 동안 스레드 풀 스레드를 풀로 반환할 수 있으므로 IIS가 전체적으로 더 많은 요청을 처리할 수 있습니다.
반면에, 스스로 새 스레드를 생성하는 것은 스레드 풀 스레드를 사용하지 않습니다.확인되지 않은 수의 독립 스레드를 생성하는 것도 문제가 될 수 있으므로 IIS 스레드 풀 문제를 모두 해결하는 것은 아닙니다.일반적으로 어느 쪽이든 비동기 IO가 선호됩니다.
스레드 풀의 스레드 수를 변경하려면 여기를 확인하십시오.하지만, 여러분은 아마도 그렇게 하는 것을 정말 피해야 할 것입니다.
당사의 웹 서비스는 초당 100개의 요청을 처리하고 나머지 시간은 초당 1개의 요청을 처리해야 합니다.IIS 로그를 분석한 결과 이러한 호출을 처리하는 데 버스트가 발생하는 데 약 28초가 걸린 것으로 나타났습니다.
@nunespascal이 언급한 Microsoft 모범 사례를 적용하면 이 경우 시간이 1초로 대폭 단축됩니다.
아래는 현재 프로덕션 서버를 배포할 때 사용하는 Powershell 스크립트입니다.논리적 프로세서 번호를 고려하여 machine.config를 업데이트합니다.
<# Get and backup current machine.config #>
$path = "C:\Windows\Microsoft.Net\Framework\v4.0.30319\Config\machine.config";
$xml = [xml] (get-content($path));
$xml.Save($path + "-" + (Get-Date -Format "yyyyMMdd-HHmm" ) + ".bak");
<# Get number of physical CPU #>
$physicalCPUs = ([ARRAY](Get-WmiObject Win32_Processor)).Count;
<# Get number of logical processors #>
$logicalProcessors = (([ARRAY](Get-WmiObject Win32_Processor))[0] | Select-Object “numberOfLogicalProcessors").numberOfLogicalProcessors * $physicalCPUs;
<# Set Number of connection in system.net/connectionManagement #>
$systemNet = $xml.configuration["system.net"];
if (-not $systemNet){
$systemNet = $xml.configuration.AppendChild($xml.CreateElement("system.net"));
}
$connectionManagement = $systemNet.connectionManagement;
if (-not $connectionManagement){
$connectionManagement = $systemNet.AppendChild($xml.CreateElement("connectionManagement"));
}
$add = $connectionManagement.add;
if(-not $add){
$add = $connectionManagement.AppendChild($xml.CreateElement("add")) ;
}
$add.SetAttribute("address","*");
$add.SetAttribute("maxconnection", [string]($logicalProcessors * 12) );
<# Set several thread settings in system.web/processModel #>
$systemWeb = $xml.configuration["system.web"];
if (-not $systemWeb){
$systemWeb = $xml.configuration.AppendChild($xml.CreateElement("system.web"));
}
$processModel = $systemWeb.processModel;
if (-not $processModel){
$processModel = $systemWeb.AppendChild($xml.CreateElement("processModel"));
}
$processModel.SetAttribute("autoConfig","true");
$processModel.SetAttribute("maxWorkerThreads","100");
$processModel.SetAttribute("maxIoThreads","100");
$processModel.SetAttribute("minWorkerThreads","50");
$processModel.SetAttribute("minIoThreads","50");
<# Set other thread settings in system.web/httRuntime #>
$httpRuntime = $systemWeb.httpRuntime;
if(-not $httpRuntime){
$httpRuntime = $systemWeb.AppendChild($xml.CreateElement("httpRuntime"));
}
$httpRuntime.SetAttribute("minFreeThreads",[string]($logicalProcessors * 88));
$httpRuntime.SetAttribute("minLocalRequestFreeThreads",[string]($logicalProcessors * 76));
<#Save modified machine.config#>
$xml.Save($path);
이 솔루션은 지난 2009년 Stuart Brierley가 작성한 블로그 기사에서 나온 것입니다.2008년 R2부터 2016년까지 윈도우즈 서버에서 성공적으로 테스트했습니다.
사실 당신이 링크한 기사에 적힌 내용은 사실이 아닙니다.비동기 패턴은 "매우 비싼 IIS 작업자 스레드"를 해제하고 다른 "저렴한 스레드"를 백그라운드에서 사용할 수 없습니다.
비동기 패턴은 단순히 스레드를 자유롭게 하기 위한 것입니다.스레드가 필요하지 않은 시나리오(로컬 시스템도 필요하지 않은 경우)에서도 이점을 누릴 수 있습니다.
두 가지 예 시나리오(I/O 모두)를 지정할 수 있습니다.
첫 번째:
- 요청 시작
- 비동기 파일 읽기 시작
- 파일 읽기 중에는 스레드가 필요하지 않으므로 다른 요청에서 사용할 수 있습니다.
- 파일 읽기 종료 - 앱 풀에서 스레드를 가져옵니다.
- 요청이 완료되었습니다.
그리고 거의 똑같은 두 번째:
- 요청 시작
- WCF 서비스에 대한 비동기 호출을 시작합니다.
- 우리는 우리의 기계를 떠날 수 있고 우리의 스레드가 필요하지 않습니다. 그래서 다른 요청들이 그것을 사용할 수 있습니다.
- 원격 서비스에서 응답을 받고 계속하려면 앱 풀에서 스레드를 얻습니다.
- 요청이 완료되었습니다.
보통 msdn을 읽는 것이 안전합니다.비동기 패턴에 대한 정보는 여기에서 확인할 수 있습니다.
언급URL : https://stackoverflow.com/questions/12304691/why-are-iis-threads-so-precious-as-compared-to-regular-clr-threads
'programing' 카테고리의 다른 글
| CSS - 선택한 라디오 버튼 레이블을 스타일화하는 방법? (0) | 2023.08.29 |
|---|---|
| mariadb의 자동 타임스탬프에 대해 너무 멍청함 (0) | 2023.08.29 |
| Jquery를 사용하여 인수가 있는 php 함수 호출 (0) | 2023.08.24 |
| 두 개의 인라인 블록, 폭 50% 요소가 두 번째 선으로 감깁니다. (0) | 2023.08.24 |
| Powershell: 프로세스 개체에 대한 표준 출력 및 오류 캡처 (0) | 2023.08.24 |