'.NET/WCF'에 해당되는 글 2건

  1. 2009.11.20 WCF 성능 향상 팁 (2)
  2. 2009.03.07 WCF 의 불친절한 ProtocolException

WCF 성능 향상 팁

.NET/WCF 2009. 11. 20. 08:30 |

WCF Performance Optimization Tips

.NET Framework 3.0 부터는 Enterprise Services 를 잘 구현할 수 있는 WCF(Windows Communication Foundation) 라이브러리를 제공합니다. 특히 최근 .NET Framework 3.5 SP1 에서는 서비스의 통합 뿐만 아니라 Enterprise Services Bus 를 구현하여 최상의 SOA(Services Oriented Architecture) 를 구현할 수 있는 프레임워크입니다.

그렇기 때문에 기존에 .NET 이 제공하던 XML Web Services 와 WCF 를 동일 선상에서 비교하거나 생각하는 것은 굉장히 위험할 수 있습니다. 가끔 BasicHttpBinding 이나 WSHttpBinding 등을 사용하여 IIS 에 호스팅 할 경우 성능에 대해 고민을 해 보신 분들도 계실 겁니다. 예전에 XML Web Service 로 잘 수행했던 프로젝트를 WCF 를 사용하여 만들었을 경우 서버가 자주 뻗는 경우도 있었을 것입니다.

   

Web Based Performance Optimization Tips

즉, 일반적으로 IIS 에 호스팅되는 Web Application 이나 XML Web Service 의 성능을 향상시키기 위해서는 Thread 나 Connection 을 늘려주는 방법으로 성능 튜닝을 할 수 있었습니다. ( default 는 .NET Framework 1.1 기준 )

  • Max Connection - default 2
  • Max IO Threads - default 20
  • Max Worker Threads - default 20
  • Min Free Threads - default 8
  • Min Local Request Free Threads - default 4

잘 모르시겠다구요~? MSDN 에 보시면 나옵니다. 각각 항목은 단지 권장 값이고 튜닝을 하기 위해서는 "추천 수치 * CPU 개수" 가 바로 최상의 성능을 낼 수 있는 Threads 나 Connection 이 됩니다. 사실 기본 값으로 서버 성능을 최상으로 발휘하기에는 무리가 있습니다.

   

WCF Based Performance Optimization Tips

하지만 WCF 에서는 이러한 성능 튜닝 방법은 전혀 다른 차원의 이야기 입니다. 왜냐하면 Web Application 이나 XML Web Service 와 달리 WCF 는 ASP.NET Pipeline(파이프라인) 을 거치지 않기 때문입니다.

Microsoft 의 WCF 개발 팀은 이런 부분에서 참 아이러니한 이야기를 합니다.

"DDos 공격을 방지하기 위함이다!" 라고...

틀린 이야기는 아니죠. ASP.NET HttpRuntime 환경을 그대로 WCF 환경으로 적용하기에는 WCF 프레임워크의 아키텍처와는 너무나 비호환적이기 때문인 것 같습니다. 다시 바꾸어 말하면, WCF 는 내부적인 ASP.NET 파이프라인을 타지 않습니다. 그렇기 때문에 기본 옵션의 Session 이나 Call 옵션으로 Service Host 가 락(Lock) 에 걸리는 상황이 옵니다.

MaxConcurrentSessions 는 Default 가 10 이므로, Closing 되지 않은 클라이언트의 세션이 이를 초과하게 되면 Lock 이 걸리게 됩니다. 아래는 간단한 예제이지만, Closing 을 잘해주더라도 Multi Thread 로 테스트를 해 보시면 금방 Lock 이 걸리게 할 수 도 있답니다.

namespace WcfService1Console

{

class Program

{

static void Main(string[] args)

{

for (int i = 0; i < 20; i++)

{

ServiceReference1.Service1Client client = new WcfService1Console.ServiceReference1.Service1Client();

Console.WriteLine(i + " " + client.GetData(3));

}

}

}

}

 

WCF 서비스는 기본값이 Max Session 이 10개에 도달하면 클라이언트의 연결을 거부합니다. Session Lock 이 걸리고 이전의 세션이 끝나야 다른 Session 의 연결을 수락하게 됩니다. WCF Session 은 HTTP Session 과 다르며, 클라이언트와 서버의 인스턴트를 연결하는 인증 매커니즘과 비슷합니다. WCF 의 SessionMode 를 NotAllowed 로 동작하도록 세션 사용을 하지 않도록 설정해도 되지만, 이러한 방법으로는 클라이언트와 서버간의 연결을 보장하지 않을 뿐이지, 실제로 세션이 연결이 되지 않는 것은 아니기 때문에, 퍼포먼스 향상을 위한 좋은 방법이라고 볼 수는 없습니다.

그리하여 WCF 의 퍼포먼스를 향상시키기 위해서는 ASP.NET 과는 별도의 Throttling 환경의 조정이 필요합니다.

<behaviors>

<serviceBehaviors>

<behavior name="WcfWsHttpSvc.Service1Behavior">

<!-- 메타데이터 정보를 공개하지 않으려면 배포하기 전에 아래의 값을 false로 설정하고 위의 메타데이터 끝점을 제거하십시오. -->

<serviceMetadata httpGetEnabled="true"/>

<serviceThrottling maxConcurrentCalls="50"

maxConcurrentSessions="50"

maxConcurrentInstances="100"/>

<!-- 디버깅 목적으로 오류에서 예외 정보를 받으려면 아래의 값을 true로 설정하십시오. 예외 정보를 공개하지 않으려면 배포하기 전에 false로 설정하십시오. -->

<serviceDebug includeExceptionDetailInFaults="false"/>

</behavior>

</serviceBehaviors>

</behaviors>

그리고 다시 테스트를 해보시면 Lock 이 걸리지 않는 것을 확인할 수 있습니다.

이 옵션은 아래와 같은 튜닝하는 것이 좋다고 가이드 합니다. 단지 권장 값이기 때문에 더 높은 값을 주어도 상관은 없습니다. 특히 MaxConcurrentInstances 는 Int32.MaxValue 값을 주셔도 됩니다. WCF 어플리케이션 서버의 배치와 Load-Balancing 을 고려하여 적절하게 주시면 됩니다.

  

기본 값

권장 값

예 (4-Core)

MaxConcurrentSessions

10

기본 값 * CPUs

40

MaxConcurrentCalls

16

기본 값 * CPUs

64

MaxConcurrentInstances

26

권장 값의 MaxConcurrentSessions + MaxConcurrentCalls

104

   

'.NET > WCF' 카테고리의 다른 글

WCF 성능 향상 팁  (2) 2009.11.20
WCF 의 불친절한 ProtocolException  (0) 2009.03.07
Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. Ryunad 2011.01.29 12:07 Address Modify/Delete Reply

    정말 좋은 것을 배워갑니다.
    감사합니다 ^^

  2. 신동열 2014.08.21 10:13 Address Modify/Delete Reply

    안그래도 이문제로 고민하고 있었는데 좋은글 보고 배워갑니다.

오늘 WCF 서비스를 만들고 열심히 쓰고 있었습니다. 하지만 어느 순간 클라이언트 어플리케이션은 동작을 하지 않네요. 뭔가 이것저것 코드를 추가하였는데, 알 수 없는 오류가 나타나서 저를 괴롭히더군요.
 

[그림1] WCF 가 보여주는 예외 정보
 

[그림2] WCF 가 보여주는 예외 정보
 
서버가 Faulted 상태가 되었기에, 우선은 서버 측 오류임을 예감하였습니다. 하지만 예외 정보만으로 자세한 원인을 찾기 힘들었습니다.
 
이리저리 검색하면서 이곳을 통해 WCF 가 알려주는 예외 정보는 충분히 설명적이지 않다는 것을 알게 되었고, 다른 외국 포럼에서도 동일한 예외 정보지만 전혀 다른 방법으로 해결한 내용은 그다지 저에게 도움이 되지 않았습니다.
 
일단 로컬에서 SVCUtil.EXE 를 이용하여 다시 한번 Proxy 코드를 생성해 보았습니다. 그전에 띄워놓고 있던 CMD 창이 있어서 아무 생각 없이 다시 실행시켜 봤을 뿐이랍니다. ^^;
 
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
 
C:\경로는 생략>svcutil http://localhost/Dx-HTTP-WCF-NETFx3/POCServiceNETFx3.svc
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, 버전 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.
 
WS-Metadata Exchange 또는 DISCO를 사용하여 'http://localhost/Dx-HTTP-WCF-NETFx3/
POCServiceNETFx3.svc'에서 메타데이터를 다운로드하고 있습니다.
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, 버전 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.
 
오류: http://localhost/Dx-HTTP-WCF-NETFx3/POCServiceNETFx3.svc에서 메타데이터를
가져올 수 없습니다.
 
액세스 권한이 있는 Windows (R) Communication Foundation 서비스일 경우 지정한 주
소에서 메타데이터 게시를 사용하도록 설정했는지 확인하십시오. 메타데이터 게시 설
정에 대한 도움말을 보려면 http://go.microsoft.com/fwlink/?LinkId=65455의 MSDN 설
명서를 참조하십시오.
 
 
WS-Metadata Exchange 오류
    URI: http://localhost/Dx-HTTP-WCF-NETFx3/POCServiceNETFx3.svc
 
    메타데이터에 확인할 수 없는 참조가 포함되었습니다. 'http://localhost/Dx-HTTP
-WCF-NETFx3/POCServiceNETFx3.svc'.
 
    응답 메시지의 콘텐츠 형식 text/html; charset=utf-8이(가) 바인딩의 콘텐츠 형
식(application/soap+xml; charset=utf-8)과 일치하지 않습니다. 사용자 지정 인코터
를 사용 중인 경우 IsContentTypeSupported 메서드가 올바르게 구현되는지 확인하십시
오. 응답의 처음 1024바이트가 '<html>
    <head>
        <title>구성 오류</title>
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:bl
ack;}
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5p
x}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
 
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red
}
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maro
on }
         pre {font-family:"Lucida Console";font-size: .9em}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy;
cursor:hand; }
        </style>
    </head>
 
    <body bgcolor="white">
 
            <span><H1>'/Dx-HTTP-WCF-NETFx3' 응용 프로그램에 서버 오류가 있습니다
.<hr width=100% size=1 color=silver></H1>
 
            <h2>'입니다.
 
    원격 서버에서 (500) 내부 서버 오류 오류를 반환했습니다.
 
 
HTTP GET Error
    URI: http://localhost/Dx-HTTP-WCF-NETFx3/POCServiceNETFx3.svc
 
   'http://localhost/Dx-HTTP-WCF-NETFx3/POCServiceNETFx3.svc'을(를) 다운로드하
는 동안 오류가 발생했습니다.
 
    다음 오류 메시지로 인해 요청하지 못했습니다.
--
<html>
    <head>
        <title>구성 오류</title>
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:bl
ack;}
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5p
x}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
 
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red
}
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maro
on }
         pre {font-family:"Lucida Console";font-size: .9em}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy;
cursor:hand; }
        </style>
    </head>
 
    <body bgcolor="white">
 
            <span><H1>'/Dx-HTTP-WCF-NETFx3' 응용 프로그램에 서버 오류가 있습니다
.<hr width=100% size=1 color=silver></H1>
 
            <h2> <i>구성 오류</i> </h2></span>
 
            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">
 
 
            <b> 설명: </b>이 요청을 제공하는 데 필요한 구성 파일을 처리하는 동안
 오류가 발생했습니다. 아래의 오류 정보를 확인한 다음 구성 파일을 적절하게 수정하
십시오.
            <br><br>
 
            <b> 파서 오류 메시지: </b>신뢰 수준 'full'의 보안 정책 파일을 읽을
수 없습니다.<br><br>
 
            <b>소스 오류:</b> <br><br>
 
            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>
 
[관련된 소스 줄 없음]</pre></code>
 
                  </td>
               </tr>
            </table>
 
            <br>
 
            <b> 소스 파일: </b> <b> ?? 줄: </b> 0
            <br><br>
 
            <hr width=100% size=1 color=silver>
 
            <b>버전 정보:</b>?Microsoft .NET Framework 버전:2.0.50727.3074; ASP.
NET 버전:2.0.50727.3074
 
            </font>
 
    </body>
</html>
<!--
[ConfigurationErrorsException]: 신뢰 수준 'full'의 보안 정책 파일을 읽을 수 없습
니다.
   위치: System.Web.HttpRuntime.SetTrustLevel(TrustSection trustSection, Securit
yPolicySection securityPolicySection)
   위치: System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags
)
[HttpException]: 신뢰 수준 'full'의 보안 정책 파일을 읽을 수 없습니다.
   위치: System.Web.HttpRuntime.FirstRequestInit(HttpContext context)
   위치: System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)
   위치: System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequ
est wr, HttpContext context)
-->
--.
 
자세한 정보를 보려면 "svcutil /?"을(를) 입력하십시오.
 
C:\경로는 생략>
 
네 그랬습니다 ㅠ
 
서버의 도메인 Security 만으로 로깅 작업을 할 수 없었기 때문에 Security 권한을 Full 로 준 것이 화근이었습니다.
 

[그림3] config 의 열거형을 소문자로 쓰면 대략 난감^^;
 

[그림4] 반드시 대문자로…
 
Config 파일의 열거형 타입은 대소문자를 구분하는 경우가 대부분인데, 이런 실수는 대략 안타까운 경우였습니다.

'.NET > WCF' 카테고리의 다른 글

WCF 성능 향상 팁  (2) 2009.11.20
WCF 의 불친절한 ProtocolException  (0) 2009.03.07
Posted by 땡초 POWERUMC
TAG wcf

댓글을 달아 주세요