ThreadPool 사용.ASP의 QueueUserWorkItem.고트래픽 시나리오에서의 NET
저는 항상 (비중요한) 단시간 백그라운드 태스크에 ThreadPool을 사용하는 것이 ASP에서도 베스트 프랙티스로 간주된다고 생각해 왔습니다.NET, 그런데 이 기사를 보게 되었습니다.그것은 다른 제안을 하고 있는 것 같습니다.그 주장은 스레드풀을 떠나 ASP를 처리해야 한다는 것입니다.NET 관련 요구
지금까지의 소규모 비동기 작업은 다음과 같습니다.
ThreadPool.QueueUserWorkItem(s => PostLog(logEvent))
이 기사에서는 대신 다음과 같은 스레드를 명시적으로 작성할 것을 제안하고 있습니다.
new Thread(() => PostLog(logEvent)){ IsBackground = true }.Start()
첫 번째 방법은 관리 및 경계가 가능하다는 장점이 있지만 (기사가 올바른 경우) 백그라운드 태스크가 ASP와 스레드를 경쟁할 가능성이 있습니다.NET 요구 핸들러두 번째 방법은 ThreadPool을 개방하지만 제한이 없기 때문에 리소스를 너무 많이 사용할 수 있습니다.
그래서 제 질문은 기사의 조언이 옳은가 하는 것입니다.
사이트에 트래픽이 너무 많아서 ThreadPool이 꽉 찼다면 Out-of-Band로 하는 것이 좋습니까? 아니면 ThreadPool이 꽉 차면 리소스가 제한된다는 것을 의미합니까? 이 경우 자체 스레드를 시작하지 않아야 합니다.
설명:저는 단지 중요하지 않은 작은 비동기 작업(리모트로깅 등)의 범위에서 묻고 있을 뿐이며, 별도의 프로세스를 필요로 하는 고가의 작업 항목이 아닙니다(이 경우 보다 견고한 솔루션이 필요하다는 데 동의합니다.
여기에 있는 다른 답변들은 가장 중요한 요점을 빠뜨리고 있는 것 같습니다.
부하가 낮은 사이트에서 CPU 부하가 높은 작업을 보다 빠르게 수행하기 위해 병렬 처리를 시도하지 않는 한 워커 스레드를 사용하는 것은 의미가 없습니다.
은 두 개의 스레드에 되며, 이 스레드는 에 의해 됩니다.new Thread(...)
의 스레드ThreadPool
에 QueueUserWorkItem
청한한다
그래, 맞아, 넌 굶길 수 있어ThreadPool
ASP の asp asp asp asp asp asp asp너무 많은 작업 항목을 대기열에 넣고 NET 프로세스를 수행합니다.ASP の asp asp asp asp asp asp 。NET에 의한 것입니다.는 그은 이 pool pool pool에 사용된 것과 .이러한 정보에 사용되는 스레드 풀은QueueUserWorkItem
는 요청을 처리하는 데도 사용됩니다.
그러나 실제로 작업 항목을 대기열에 넣고 있으면 스레드 풀이 부족해질 수 있습니다.말 그대로 수백 개의 CPU 부하가 높은 작업을 동시에 실행하고 있다면 ASP에 서비스를 제공하는 다른 워커 스레드가 있으면 어떤 이점이 있을까요?NET 요청, 머신이 이미 과부하 상태일 때?이 상황에 처하게 되면 완전히 재설계해야 합니다.
대부분의 경우 멀티 스레드코드가 ASP에서 부적절하게 사용되고 있다는 것을 보거나 듣습니다.NET, CPU를 많이 사용하는 작업을 큐잉하기 위한 것이 아닙니다.큐잉 I/O 바운드 작업용입니다.I/O 작업을 수행하려면 I/O 스레드(I/O 완료 포트)를 사용해야 합니다.
특히 사용하는 라이브러리 클래스에서 지원되는 비동기 콜백을 사용해야 합니다.은 항상 이 붙어 . 즉, '아까부터 합니다.'라는 단어부터 시작합니다.Begin
★★★★★★★★★★★★★★★★★」End
에서와 같이Stream.BeginRead
,Socket.BeginConnect
,WebRequest.BeginGetResponse
기타 등등.
이러한 방법에서는,ThreadPool
단, ASP를 방해하지 않는 IOCP를 사용합니다.NET 요구이들은 I/O 시스템으로부터의 인터럽트 신호에 의해 "웨이크업"될 수 있는 특별한 종류의 경량 스레드입니다.ASP에서도요NET 어플리케이션에서는 보통 워커 스레드마다 1개의 I/O스레드가 있기 때문에 모든 요구는 1개의 비동기 조작을 큐잉할 수 있습니다.이는 성능 저하 없이 말 그대로 수백 개의 비동기 작업을 수행하는 것입니다(I/O 서브시스템이 이를 따라갈 수 있다고 가정).당신이 필요로 하는 것보다 훨씬 더 많이요.
비동기 대리인은 이러한 방식으로 작업하지 않습니다. 이들은 다음과 같이 작업자 스레드를 사용하게 됩니다.ThreadPool.QueueUserWorkItem
일 뿐입니다.「NET Framework」를 참조해 주세요.직접 할 수 있지만, 복잡하고 조금 위험하며 아마도 이 논의의 범위를 벗어납니다.
이 질문에 대한 최선의 답변은 ASP에서 또는 백그라운드인스턴스를 사용하지 않는 것입니다.NET. Windows Forms 응용 프로그램에서 스레드를 회전시키는 것과 전혀 다릅니다. UI의 응답성을 유지하기 위해 스레드를 회전시키는 것은 효율성에 대한 관심이 없습니다.ASP에서.NET은 throughput에 대한 우려입니다.이러한 모든 워커 스레드에서의 컨텍스트 전환으로 인해 스루풋이 완전히 중단됩니다.ThreadPool
그렇지 않으면.
만약 당신이 스레드 코드를 ASP에 쓰는 것을 발견한다면, 부탁한다.NET - 기존 비동기 메서드를 사용하도록 다시 작성할 수 있는지, 그렇지 않을 경우 백그라운드 스레드에서 실행할 코드가 정말로 필요한지 여부를 고려하십시오.대부분의 경우 복잡성이 가중되어도 실익이 없을 것입니다.
ASP의 Thomas Marquadt에 따르면.Microsoft의 NET 팀은 ASP를 사용하는 것이 안전합니다.NET ThreadPool(QueueUserWorkItem).
Q) ASP의 경우NET 응용 프로그램은 CLR 스레드 풀 스레드를 사용합니다.ASP가 부족하지 않습니다.NET, CLR ThreadPool을 사용하여 요청을 실행합니까? ..
A) 요약하자면, ASP가 굶주릴 염려가 없습니다.NET 스레드, 그리고 여기에 문제가 있다고 생각되면 알려주시면 저희가 처리해 드리겠습니다.
Q) 독자적인 스레드(새로운 스레드)를 작성해야 합니까?ASP에 더 좋지 않을까요?NET, CLR 스레드 풀을 사용하기 때문에
A) 하지 말아 주세요.아니면 다르게 말하면 안돼!!!저보다 훨씬 더 똑똑하다면 자신만의 스레드를 만들 수 있습니다.그렇지 않으면 생각하지 마세요.새로운 스레드를 자주 작성하지 않는 이유는 다음과 같습니다.
- QueueUserWorkItem에 비해 매우 비쌉니다.덧붙여서, 만약 당신이 CLR보다 더 나은 ThreadPool을 쓸 수 있다면, 마이크로소프트에 지원하기를 권합니다. 왜냐하면 우리는 분명히 당신 같은 사람을 찾고 있기 때문입니다!
웹사이트는 산란기를 돌면 안 된다.
통상, 이 기능은 Windows 서비스로 이동해, 다음에 통신합니다(MSMQ 를 사용해 통신합니다).
--편집
여기서 구현에 대해 설명했습니다.ASP에서의 큐 기반 백그라운드 처리입니다.NET MVC 웹 응용 프로그램
--편집
이것이 단순한 스레드보다 더 나은 이유를 확장하려면:
MSMQ 를 사용하면, 다른 서버와 통신할 수 있습니다.머신간의 큐에 쓸 수 있기 때문에, 어떠한 이유로 백그라운드 태스크가 메인 서버의 자원을 너무 많이 소비하고 있다고 판단했을 경우는, 3회 간격으로 변경할 수 있습니다.
또한 수행하려는 모든 작업(전자 메일 보내기/모든 작업)을 일괄 처리할 수 있습니다.
ASP에서 우선순위가 낮은 빠른 비동기 작업을 위한 일반적인 관행이라고 생각합니다.NET은 을 사용하는 것입니다.NET 스레드 풀, 특히 리소스를 제한하려는 트래픽량이 많은 시나리오의 경우.
또한 스레드의 실장은 숨겨져 있습니다.스스로 스레드를 산란하기 시작하면 스레드도 적절히 관리해야 합니다.할 수 없다는 게 아니라 왜 바퀴를 다시 만들었을까?
퍼포먼스가 문제가 되어 스레드 풀이 제한 요인(데이터베이스 접속, 발신 네트워크 접속, 메모리, 페이지 타임아웃 등이 아님)임을 확인할 수 있는 경우 스레드 풀 구성을 조정하여 더 많은 워커 스레드, 더 높은 큐잉 요구 등을 허용합니다.
성능 문제가 없는 경우 ASP와의 경합을 줄이기 위해 새 스레드를 생성하도록 선택합니다.NET 요청 큐는 전형적인 조기 최적화입니다.
로그 조작에 개별 스레드를 사용할 필요는 없습니다.원래 스레드가 가능한 한 신속하게 조작을 완료할 수 있도록 하는 것만으로, MSMQ와 개별의 컨슈머 스레드/프로세스가 실현됩니다.이것이 더 무겁고 구현해야 할 작업이 많다는 것은 인정하지만, 여기서는 내구성이 정말 필요합니다.공유 메모리 내 큐의 변동성은 곧 환영을 잃게 됩니다.
QueueUserWorkItem을 사용하여 페스트를 회피하는 것과 같은 새로운 스레드를 작성하지 않도록 해야 합니다.ASP를 굶기지 않는 이유를 설명하는 비주얼을 위해.NET은 같은 ThreadPool을 사용하기 때문에 매우 숙련된 저글러가 두 손으로 볼링 핀이나 칼 등을 6개씩 가지고 있다고 상상해 보십시오.자신만의 스레드를 만드는 것이 왜 나쁜지에 대한 시각적인 설명을 위해, 고속도로 진입로를 많이 사용하는 차량이 조명을 사용하고 출입구 수를 몇 초마다 1개로 제한하는 대신 즉시 진입할 수 있도록 하는 출퇴근 시간에 시애틀에서 무슨 일이 벌어졌는지 상상해 보십시오.마지막으로 자세한 설명은 다음 링크를 참조하십시오.
고마워, 토마스
그 기사는 정확하지 않다.ASP.NET에는 ASP 서비스를 위한 자체 스레드 풀(관리된 워커 스레드)이 있습니다.NET 요구이 풀은 보통 수백 개의 스레드로 구성되어 있으며 스레드 풀(프로세서의 몇 배)과는 분리되어 있습니다.
ASP에서 ThreadPool 사용.NET은 ASP에 간섭하지 않습니다.NET 워커 스레드ThreadPool을 사용하면 됩니다.
또한 단일 스레드를 설정하는 것도 허용됩니다.이 스레드는 메시지를 로깅하기 위해 생산자/소비자 패턴을 사용하여 해당 스레드에 로그 메시지를 전달할 수 있습니다.이 경우 스레드는 수명이 길기 때문에 로깅을 실행할 새 스레드를 하나 생성해야 합니다.
모든 메시지에 새로운 스레드를 사용하는 것은 확실히 과잉입니다.
또 다른 방법은 log4net과 같은 라이브러리를 사용하는 것입니다.별도의 스레드로 로깅을 처리하고 해당 시나리오에서 발생할 수 있는 모든 컨텍스트 문제를 처리합니다.
그 기사는 잘못된 것 같아요.대규모 운영 중인 경우.NET Shop에서는 ThreadPool 설명서의 한 가지 문구를 기반으로 여러 앱과 여러 웹 사이트에서 풀을 안전하게 사용할 수 있습니다(별도의 앱 풀 사용).
프로세스당 스레드 풀이 1개씩 있습니다.스레드 풀의 디폴트 사이즈는 프로세서당 250개의 워커 스레드와 1000개의 I/O 완료 스레드입니다.스레드 풀의 스레드 수는 SetMaxThreads 메서드를 사용하여 변경할 수 있습니다.각 스레드는 기본 스택 크기를 사용하며 기본 우선순위로 실행됩니다.
지난주 회사에서도 비슷한 질문을 받았는데 같은 답변을 드리겠습니다.요청마다 웹 애플리케이션을 여러 개 스레드화하는 이유는 무엇입니까?웹 서버는 많은 요구를 시기적절하게(멀티 스레드화 등) 제공하도록 고도로 최적화된 환상적인 시스템입니다.웹에서 거의 모든 페이지를 요청할 때 어떤 일이 일어나는지 생각해 보십시오.
- 어떤 페이지에 대한 요청이 있습니다.
- Html은 반환됩니다.
- Html은 클라이언트에 추가 요청(js, css, 이미지 등)을 지시합니다.
- 추가 정보가 제공됩니다.
리모트 로깅의 예를 제시하지만, 로거의 문제가 됩니다.메시지를 시기적절하게 수신하려면 비동기 프로세스를 실행해야 합니다.Sam은 로거(log4net)가 이미 이를 지원해야 한다고 지적하기도 합니다.
CLR의 스레드 풀을 사용하면 IIS의 스레드 풀에 문제가 발생하지 않는다는 점에서도 Sam은 옳습니다.여기서 주의해야 할 점은 프로세스에서 스레드를 산란하는 것이 아니라 IIS 스레드 풀 스레드에서 새로운 스레드를 산란 것입니다.차이가 있고 구별이 중요하다.
스레드와 프로세스
스레드와 프로세스는 모두 응용 프로그램을 병렬화하는 방법입니다.단, 프로세스는 독자적인 상태 정보를 포함하고, 독자적인 주소 공간을 사용하며, 프로세스 간 통신 메커니즘(일반적으로 운영체제에 의해 관리됨)을 통해서만 상호 작용하는 독립된 실행 유닛입니다.애플리케이션은 일반적으로 설계 단계에서 프로세스로 분할되며, 마스터 프로세스는 중요한 애플리케이션 기능을 논리적으로 분리하는 것이 타당할 때 하위 프로세스를 명시적으로 생성합니다.다시 말해 프로세스는 아키텍처 구조입니다.
이와는 대조적으로, 스레드는 애플리케이션의 아키텍처에 영향을 미치지 않는 코딩 구조입니다.단일 프로세스에는 여러 스레드가 포함될 수 있습니다. 프로세스 내의 모든 스레드는 동일한 상태와 메모리 공간을 공유하며 동일한 변수를 공유하기 때문에 서로 직접 통신할 수 있습니다.
병렬을 사용할 수 있습니다.또는 병렬.ForEvery 및 원활한 실행과 풀 고갈을 방지하기 위해 할당할 수 있는 스레드의 제한을 정의합니다.
단, 백그라운드에서 실행할 경우 ASP에서 아래의 순수 TPL 스타일을 사용해야 합니다.인터넷 웹 어플리케이션
var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;
ParallelOptions po = new ParallelOptions();
po.CancellationToken = ts.Token;
po.MaxDegreeOfParallelism = 6; //limit here
Task.Factory.StartNew(()=>
{
Parallel.ForEach(collectionList, po, (collectionItem) =>
{
//Code Here PostLog(logEvent);
}
});
참조 기사(C#feeds.com)에 동의하지 않습니다.새로운 스레드를 만드는 것은 쉽지만 위험합니다.단일 코어로 실행할 수 있는 최적의 액티브 스레드 수는 실제로 10개 미만인 놀라울 정도로 적습니다.작은 작업을 위해 스레드가 생성되면 머신이 스레드 전환에 시간을 낭비하기 쉽습니다.스레드는 관리가 필요한 리소스입니다.WorkItem 추상화는 이를 처리하기 위한 것입니다.
이 경우 요청에 사용할 수 있는 스레드 수를 줄이는 것과 효율적으로 처리할 수 있도록 너무 많은 스레드를 생성하는 것 사이에는 트레이드오프가 있습니다.이것은 매우 역동적인 상황이지만 스레드 작성에 앞서 프로세서에 맡기는 것이 아니라 (이 경우 스레드 풀에 의해) 능동적으로 관리되어야 한다고 생각합니다.
마지막으로 이 기사는 ThreadPool을 사용하는 것의 위험성에 대해 상당히 포괄적인 언급을 하고 있지만, 이를 뒷받침할 구체적인 내용이 필요합니다.
IIS가 수신 요청을 처리하기 위해 동일한 ThreadPool을 사용하는지 여부는 명확한 답변을 얻기 어렵고 버전에 따라 변경된 것으로 보입니다.따라서 스레드 풀 스레드를 과도하게 사용하지 않는 것이 좋습니다.그러면 IIS에서 스레드 풀 스레드를 많이 사용할 수 있습니다.반면에, 작은 일마다 자신의 실타래를 치는 것은 나쁜 생각처럼 보인다.로그가 잠겨 있기 때문에 한 번에 진행할 수 있는 것은 스레드 1개뿐이며, 나머지 스레드는 스케줄과 스케줄 외(새로운 스레드를 산란하는 오버헤드는 말할 것도 없습니다)를 번갈아 실행할 수 있습니다.기본적으로 ThreadPool이 회피하도록 설계된 것과 동일한 문제에 직면하게 됩니다.
메시지를 전달할 수 있는 단일 로깅 스레드를 앱에 할당하는 것이 합리적인 방법인 것 같습니다.앱의 속도가 느려지지 않도록 가능한 한 빨리 메시지를 보낼 수 있도록 주의해야 합니다.
언급URL : https://stackoverflow.com/questions/1325718/using-threadpool-queueuserworkitem-in-asp-net-in-a-high-traffic-scenario
'programing' 카테고리의 다른 글
기본값 대응:다음 키보드 버튼을 누른 후 다음 텍스트 입력을 선택하는 방법은 무엇입니까? (0) | 2023.04.26 |
---|---|
Bash에서는 대괄호[ ]가 대괄호[ ]보다 좋습니까? (0) | 2023.04.21 |
인수 없이 펑크를 무효화하다 (0) | 2023.04.21 |
grep에서 .svn 디렉토리 제외 (0) | 2023.04.21 |
(colon) GNU Bash 빌트인의 목적은 무엇입니까? (0) | 2023.04.21 |