Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

눈으로 확인하는 connectionManagement의 maxconnection 설정값


"눈으로 확인하는..." 시리즈 물이 될 것 같군요. ^^

눈으로 확인하는 maxWorkerThreads, minFreeThreads 설정값
; https://www.sysnet.pe.kr/2/0/983

이번에는 connectionManagement 노드에서 제공되는 maxconnection 값에 대한 테스트를 해보겠습니다. 이 값은 .NET 응용 프로그램에서 특정 호스트로 보내는 "동시 연결 수"를 제어합니다. 쉽게 풀어보면, 여러분들의 .NET 응용 프로그램에서 HttpWebRequest를 이용하여 다음과 같이 연결을 한다고 가정할 때,

string url = "http://testhost/test.aspx";
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
                
using (HttpWebResponse httpResponse = req.GetResponse() as HttpWebResponse)
using (Stream stream = httpResponse.GetResponseStream())
using (StreamReader sr = new StreamReader(stream, Encoding.Default))
{
    string txt = sr.ReadToEnd();
}

만약, test.aspx 내의 코드 수행 시간이 10초가 걸리는 상황에서 위의 코드를 스레드 100개로 돌리면 maxconnection에 지정된 수의 스레드만 testhost 컴퓨터에 연결이 되고 나머지 스레드들의 HttpWebRequest 개체들은 10초가 지난 후 기존 연결들이 해제되고 나서야 하나씩 차례대로 접속할 수 있는 효과가 있습니다.

덧붙여, 아래의 문서에 보면 maxconnection에 대한 설명이 잘 나와 있습니다.

<add> Element for connectionManagement (Network Settings)
; https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/add-element-for-connectionmanagement-network-settings

Don't forget to tune your application 
; http://weblogs.asp.net/johnbilliris/archive/2010/06/30/don-t-forget-to-tune-your-application.aspx

대부분의 app/web.config 파일에는 connectionManagement 설정이 없는데요. 그렇다면 기본값은 몇일까요?




확인을 위해 간단한 테스트 환경을 구성했습니다.

A, B 호스트를 마련했고, A 호스트의 test.aspx는 B 호스트의 delay.aspx를 호출하도록 했습니다. delay.aspx는 일부러 Page_Load에서 Thread.Sleep(60 * 1000)을 해서 60초의 지연 시간을 갖고!

(별다른 의미는 없지만, B 호스트는 Web Garden == 2로 설정했습니다.)

부하 발생기를 이용해서 A 호스트의 test.aspx에 요청을 집중했더니 아래와 같이 maxconnection == 10의 결과가 나왔습니다.

maxconnection_settings_affect_1.png

위의 그림에서 "W11"이 "A 호스트"이고, "W21", "W22"는 "Web Garden"이 2개로 설정된 "B 호스트"의 웹 응용 프로그램을 나타냅니다.

보시는 것처럼, test.aspx에서 HttpWebRequest를 이용하여 "http://bhost/delay.aspx"로 호출했을 때 최대 10개의 연결만 맺어지는 것을 볼 수 있습니다. 즉, connectionManagement의 maxconnection 기본값은 10이 됩니다.

확실히 하기 위해 이 값을 30으로 바꿔보았습니다.

<system.net>
    <connectionManagement>
        <add address="*" maxconnection="30" />
    </connectionManagement>
</system.net>

자, 그럼 결과가 어떻게 나올까요? ^^ 예상하시는 것처럼 "B 호스트"로의 연결은 각각 15개씩 총 30개의 연결로 제한이 됩니다.

maxconnection_settings_affect_2.png




한 가지 짚고 넘어가야 할 것이 있는데요. 문서가 약간 혼동스럽다는 점입니다. maxconnection이 지정되어 있지 않으면 기본값이 2라고 되어 있는데요.

maxconnection - The maximum number of connections allowed to a server. If not supplied, the default is 2.


"%Program Files%\Microsoft Visual Studio 10.0\xml\Schemas\DotNetConfig35.xsd" 파일에 명시된 바에 의하면 maxconnection은 생략할 수 없는 "required" 속성을 가지고 있습니다.

<xs:element name="connectionManagement" vs:help="configuration/system.net/connectionManagement">
    <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="add" vs:help="configuration/system.net/connectionManagement/add">
                <xs:complexType>
                    <xs:attribute name="address" type="xs:string" use="required" />
                    <xs:attribute name="maxconnection" type="xs:int" use="required" />
                    <xs:attribute name="lockAttributes" type="xs:string" use="optional" />
            ...[생략]...

그런데, 실제로 ^^; 생략이 되어 다음과 같이 설정하는 것이 가능합니다.

<system.net>
    <connectionManagement>
        <add address="*" />
    </connectionManagement>
</system.net> 

다시 부하 발생기로 테스트해 보면 값이 어떻게 나올까요?

예상했던 2가 아니라... 1입니다. (혹시, 제가 테스트를 잘못한 것 같다면 덧글 부탁드립니다.)

maxconnection_settings_affect_3.png




고객사에서 오류 문의가 왔습니다. 제니퍼 닷넷에서 다음과 같은 오류가 보고된 것입니다.

...[생략]...
[0005][13:39:23 477][ 15][ 15] TX-CALL[WebReq.http://[...this_public_domain_name...]/top.aspx] [15 ms]
[0006][13:39:23 477][ 0][ 0] SOCKET-CLOSE R=52174,W=106,uid=7568243 
[0007][13:40:03 523][40,046][ 16] TX-CALL[WebReq.http://[...this_public_domain_name...]/bottom.aspx] [40,046 ms]
[0008][13:40:03 523][ 0][ 0] TX-EXCEPTION [System.Net.WebException: 작업 시간이 초과되었습니다. ...[이하 콜스택 생략]... 

그런데... 가만 보면 해당 웹 페이지의 구성 자체가 재미있습니다. 보통 웹 페이지를 만들면 내부에 레이아웃을 구성하게 되는데요. 위의 고객 사이트는 웹 페이지의 top과 bottom에 해당하는 내용을 별도의 aspx로 빼고 사용자로부터 요청이 왔을 때 HttpWebRequest 개체를 이용해서 직접 top/bottom 관련해서 aspx를 호출하여 내용을 가져온 후 화면에 추가하는 것이었습니다.

위와 같은 구성이 성능에 어떤 영향을 미칠까요?

1) 우선, 해당 고객 사이트가 web.config에 connectionManagement / maxconnection 설정을 하지 않았다고 가정해 보겠습니다. 이 글의 처음에 설명했던 것처럼 특정 호스트에 대해 동시 연결이 기본값 10으로 동작하기 때문에, 위의 웹 사이트는 마치 10개의 상한을 가진 세마포어를 사용하는 효과를 가지게 됩니다. 동시 연결 10개 이후부터는 쓰레드들이 대기 현상이 발생하게 되고 사용자가 폭주하는 시간에는 그 현상이 더욱 심하게 됩니다.

게다가 위에서는 top과 bottom에 대해 각각 요청을 보냈기 때문에 스레드 대기 현상은 더욱 심해집니다.

2) 두 번째 문제는, HttpWebRequest 요청의 URL에 내부 IP가 아닌, 일반 사용자들이 접근할 때와 동일한 공용 DNS 이름을 사용했다는 것입니다. 이렇게 되면 내부 IP가 아닌 외부 공용 IP가 구해지게 되고, 방화벽/NAT/L4 장비를 거쳐서 호출이 되어 응답 시간이 늘어나게 됩니다.

3) 세 번째 문제는, dead-lock 문제에 빠질 수 있습니다. 이에 대해서는 지난번에도 한번 사례를 설명했었습니다.

제니퍼 닷넷 적용 사례 (2) - 웹 애플리케이션 hang의 원인을 알려주다.
; https://www.sysnet.pe.kr/2/0/1117

위의 글에서는 config.xml 파일 하나를 서비스하는 유형이라서 간단하게 AppPool을 별도로 생성하여 스레드 풀을 새롭게 할당함으로써 해결을 했는데요. System.Net.WebException 예외가 발생한 이번 글의 고객사 경우에는 문제가 좀 복잡해 질 수 있습니다. 왜냐하면, top/bottom.aspx 요청을 받는 그 웹 사이트는 그 외에도 많은 요청을 받아서 처리할 수 있는 구조였기 때문입니다.

가정을 해볼까요? 사용자가 갑자기 몰려서 L4로 묶인 호스트 중에서 "192.168.0.10" 서버가 동시에 1,200개의 요청을 받았다고 해보겠습니다. 그 서버는 maxWorkerThreads == 100 상태에서 쿼드 코어라면 총 400개의 동시 요청만을 처리할 수가 있습니다. 나머지 800개는 IIS가 요청 대기 큐에 쌓아두고 앞서의 처리가 끝나면 차례대로 처리를 할 텐데요. 설상 가상으로 DB까지 지연되면서 하나의 aspx 처리 시간이 5초가 걸리는 상황이 발생한다고 하면?

그런 와중에 "192.168.0.11" 서버로 top/bottom.aspx를 포함한 웹 페이지 요청이 발생했고 하필 그것이 "192.168.0.10" 서버로 전달되었다고 하면 어떤 일이 벌어질까요? 현재 10번 서버에 발생한 요청만 처리하는데 1,200 / 400 = 3 * 5초 == 15초가 소요되어 11번 서버로 요청을 보냈던 사용자는 11번 서버가 한가로운데도 불구하고 15초를 대기한 후에야 정상적인 aspx 웹 페이지를 볼 수 있게 됩니다.

결론적으로, 아무리 어떤 이유를 갖다댄다 해도... 하나의 aspx에서 top/bottom.aspx의 내용을 별도의 HTTP 요청으로 분리해서 구하는 것은 꽤나 불합리한 구조입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 6/26/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2017-12-26 09시45분
[몬난아] 예전글이라 답변이 달릴지 모르겠군요..
https://docs.microsoft.com/en-us/aspnet/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45 게시글을 보다가 여기까지 왔습니다.

하단에 maxconnection관련 해서 12 * 4(cpu) = 48 부분인데요.

이게 기본설정이면 2008r2이상에서는 4cpu에서 48개정도의 동시 처리가 불가능한것인가요? 좀 혼란스러운게.. IIS같은경우는 1개의 프로세스에 25개의 Thread설정이 기본값인데. 이것과상관관계가 어떻게 되는지 머리속에 그려지지 않내요..

이럴경우 서비스 4.0으로 서비스하고 있는 프로젝트들은 좀 수동으로 늘려주는게 유리한것인지 해서 질문드립니다. 4.5가 5000이 기본값이면, 48이 아닌 여유있게 1000~3000을 줘도 여유로울것 같은설정인데..

그리고 .NET 4.5이상에서는 5000개가 기본값인것도 갭이 상당하내요..

질문이 두서없군요.. 저는 여태까지는 IIS에 1개의 어플리케이션은 별도로 옵션을 수정하지 않는다면
1개프로세스안에서 > 25개의 Thread가 대기중인상태이고 3000개 까지 큐를 받을수 있으며 큐에 쌓인순서대로 25개의 Thread 25개가 순차적으로 처리해나간다였는데.
여기 개념사이에 CPU별로 12개씩 동시 처리 여부가 어디에? 들어가야하는걸로 계산해야하는지... 그게 좀 혼란스럽내요..
[guest]
2017-12-26 09시53분
[몬난아] 큐길이 설정이.. IIS에서도 ASP 하위에 큐길이의 기본값은 3천이고.. 응용프로그램풀의 기본값은 1000이군요.
이럴경우 ASP쪽의 설정은 Classic ASP에서이고.. 닷넷은 응용프로그램풀의 큐설정을 따르는것인가요... 이게 질문의 범위가 커져버렸습니다.

만약그런것이라면 ASP 하위에 프로세스 당 Thread제한역시 ASP전용이 되는것이고 .NET은 maxconnection 인것인지..
몇가지가 기존에 알던것과 틀리고 중복된.. 혼란스럽네요.. 시간이 나시면 간단히 답변부탁드립니다
수고하세요
[guest]
2017-12-26 02시03분
[몬난아] 아 다시 차근히 읽으니 해당설정은 응용에서 특정호스트로 보내는 작업에 제한이군요....
[guest]
2019-07-30 12시57분
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Aspnet.config

<system.web>
  <applicationPool
       maxConcurrentRequestsPerCPU="12"
       maxConcurrentThreadsPerCPU="0"
       requestQueueLimit="5000"/>
</system.web>
정성태

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13610정성태4/28/2024210닷넷: 2251. C# - 제네릭 인자를 가진 타입을 생성하는 방법 - 두 번째 이야기
13609정성태4/27/2024235닷넷: 2250. PInvoke 호출 시 참조 타입(class)을 마샬링하는 [IN], [OUT] 특성파일 다운로드1
13608정성태4/26/2024427닷넷: 2249. C# - 부모의 필드/프로퍼티에 대해 서로 다른 자식 클래스 간에 Reflection 접근이 동작할까요?파일 다운로드1
13607정성태4/25/2024517닷넷: 2248. C# - 인터페이스 타입의 다중 포인터를 인자로 갖는 C/C++ 함수 연동
13606정성태4/24/2024687닷넷: 2247. C# - tensorflow 연동 (MNIST 예제)파일 다운로드1
13605정성태4/23/2024800닷넷: 2246. C# - Python.NET을 이용한 파이썬 소스코드 연동파일 다운로드1
13604정성태4/22/2024851오류 유형: 901. Visual Studio - Unable to set the next statement. Set next statement cannot be used in '[Exception]' call stack frames.
13603정성태4/21/2024957닷넷: 2245. C# - IronPython을 이용한 파이썬 소스코드 연동파일 다운로드1
13602정성태4/20/2024977닷넷: 2244. C# - PCM 오디오 데이터를 연속(Streaming) 재생 (Windows Multimedia)파일 다운로드1
13601정성태4/19/2024995닷넷: 2243. C# - PCM 사운드 재생(NAudio)파일 다운로드1
13600정성태4/18/20241015닷넷: 2242. C# - 관리 스레드와 비관리 스레드
13599정성태4/17/2024951닷넷: 2241. C# - WAV 파일의 PCM 사운드 재생(Windows Multimedia)파일 다운로드1
13598정성태4/16/2024995닷넷: 2240. C# - WAV 파일 포맷 + LIST 헤더파일 다운로드2
13597정성태4/15/20241003닷넷: 2239. C# - WAV 파일의 PCM 데이터 생성 및 출력파일 다운로드1
13596정성태4/14/20241120닷넷: 2238. C# - WAV 기본 파일 포맷파일 다운로드1
13595정성태4/13/20241072닷넷: 2237. C# - Audio 장치 열기 (Windows Multimedia, NAudio)파일 다운로드1
13594정성태4/12/20241095닷넷: 2236. C# - Audio 장치 열람 (Windows Multimedia, NAudio)파일 다운로드1
13593정성태4/8/20241095닷넷: 2235. MSBuild - AccelerateBuildsInVisualStudio 옵션
13592정성태4/2/20241232C/C++: 165. CLion으로 만든 Rust Win32 DLL을 C#과 연동
13591정성태4/2/20241209닷넷: 2234. C# - WPF 응용 프로그램에 Blazor App 통합파일 다운로드1
13590정성태3/31/20241091Linux: 70. Python - uwsgi 응용 프로그램이 k8s 환경에서 OOM 발생하는 문제
13589정성태3/29/20241196닷넷: 2233. C# - 프로세스 CPU 사용량을 나타내는 성능 카운터와 Win32 API파일 다운로드1
13588정성태3/28/20241545닷넷: 2232. C# - Unity + 닷넷 App(WinForms/WPF) 간의 Named Pipe 통신 [2]파일 다운로드1
13587정성태3/27/20241397오류 유형: 900. Windows Update 오류 - 8024402C, 80070643
13586정성태3/27/20241609Windows: 263. Windows - 복구 파티션(Recovery Partition) 용량을 늘리는 방법
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...