다음을 통해 공유


인터넷 정보 서비스 호스팅 모범 사례

이 항목에서는 WCF(Windows Communication Foundation) 서비스를 호스팅하기 위한 몇 가지 모범 사례를 간략하게 설명합니다.

WCF 서비스를 DLL로 구현

웹 애플리케이션의 \bin 디렉터리에 배포된 DLL로 WCF 서비스를 구현하면 예를 들어 IIS(인터넷 정보 서비스)가 배포되지 않은 테스트 환경에서 웹 애플리케이션 모델 외부에서 서비스를 다시 사용할 수 있습니다.

IIS-Hosted 애플리케이션의 서비스 호스트

명령형 자체 호스트 API를 사용하여 IIS 호스팅 환경에서 기본적으로 지원되지 않는 네트워크 전송에서 수신 대기하는 새로운 서비스 호스트를 만들지 마십시오(예: IIS 6.0에서 TCP 통신은 기본적으로 지원되지 않기 때문에 TCP 서비스를 호스트하는 경우). 이는 권장되는 방법이 아닙니다. 명령적으로 만든 서비스 호스트는 IIS 호스팅 환경 내에서 알 수 없습니다. 중요한 점은 호스팅 애플리케이션 풀이 유휴 상태인지 여부를 결정할 때 명령적으로 만든 서비스에서 수행하는 처리가 IIS에 의해 고려되지 않는다는 것입니다. 따라서 이러한 명령적으로 만든 서비스 호스트가 있는 애플리케이션에는 IIS 호스트 프로세스를 적극적으로 삭제하는 IIS 호스팅 환경이 있습니다.

URI들과 IIS-Hosted 엔드포인트

IIS 호스팅 서비스에 대한 엔드포인트는 절대 주소가 아닌 상대 URI(Uniform Resource Identifier)를 사용하여 구성해야 합니다. 이렇게 하면 엔드포인트 주소가 호스팅 애플리케이션에 속하는 URI 주소 집합 내에 속하며 메시지 기반 활성화가 예상대로 수행되도록 보장합니다.

상태 관리 및 프로세스 재활용

IIS 호스팅 환경은 메모리에서 로컬 상태를 유지하지 않는 서비스에 최적화되어 있습니다. IIS는 다양한 외부 및 내부 이벤트에 대한 응답으로 호스트 프로세스를 재활용하여 메모리에 독점적으로 저장된 휘발성 상태가 손실됩니다. IIS에서 호스트되는 서비스는 프로세스 외부(예: 데이터베이스) 또는 애플리케이션 재활용 이벤트가 발생할 경우 쉽게 다시 만들 수 있는 메모리 내 캐시에 해당 상태를 저장해야 합니다.

비고

WCF가 메시지 계층 안정성 및 보안에 사용하는 프로토콜은 일시적 메모리 내 상태를 사용합니다. WCF 신뢰할 수 있는 세션 및 보안 세션은 애플리케이션 재활용으로 인해 예기치 않게 종료할 수 있습니다. 이러한 프로토콜을 사용하는 IIS 호스팅 애플리케이션은 애플리케이션 계층 상태(예: 애플리케이션 계층 구문 또는 사용자 지정 상관 관계 헤더)의 상관 관계를 지정하기 위해 WCF에서 제공하는 세션 키 이외의 항목에 의존하거나 호스트된 애플리케이션에 대한 IIS 프로세스 재활용을 사용하지 않도록 설정해야 합니다.

Middle-Tier 시나리오에서 성능 최적화

들어오는 메시지에 대한 응답으로 다른 서비스를 호출하는 서비스 인 중간 계층 시나리오에서 최적의 성능을 위해 WCF 서비스 클라이언트를 원격 서비스에 한 번 인스턴스화하고 들어오는 여러 요청에서 다시 사용합니다. WCF 서비스 클라이언트 인스턴스를 인스턴스화하는 것은 기존 클라이언트 인스턴스에서 서비스 호출을 하는 것에 비해 비용이 많이 드는 작업이며, 중간 계층 시나리오는 요청 간에 원격 클라이언트를 캐싱하여 고유한 성능 향상을 생성합니다. WCF 서비스 클라이언트는 스레드로부터 안전하므로 여러 스레드에서 클라이언트에 대한 액세스를 동기화할 필요가 없습니다.

중간 계층 시나리오 또한 svcutil /a 옵션에서 생성된 비동기 API를 사용하여 성능 향상을 도출합니다. 이 /a 옵션을 사용하면 ServiceModel 메타데이터 유틸리티 도구(Svcutil.exe) 가 각 서비스 작업에 대한 메서드를 생성 BeginXXX/EndXXX 하므로 백그라운드 스레드에서 원격 서비스에 대한 잠재적으로 장기 실행 호출을 수행할 수 있습니다.

다중 홈 또는 다중 이름 시나리오의 WCF

IIS 웹 팜 내에 WCF 서비스를 배포할 수 있습니다. 여기서 컴퓨터 집합은 일반적인 외부 이름(예: http://www.contoso.com)을 공유하지만 서로 다른 호스트 이름으로 개별적으로 주소가 지정됩니다(예 http://www.contoso.com : 두 개의 서로 다른 컴퓨터로 http://machine1.internal.contoso.comhttp://machine2.internal.contoso.com트래픽을 보낼 수 있음). 이 배포 시나리오는 WCF에서 완전히 지원되지만 서비스의 메타데이터(웹 서비스 설명 언어)에 올바른(외부) 호스트 이름을 표시하려면 WCF 서비스를 호스팅하는 IIS 웹 사이트의 특별한 구성이 필요합니다.

WCF에서 생성하는 서비스 메타데이터에 올바른 호스트 이름이 표시되도록 하려면 명시적 호스트 이름을 사용하도록 WCF 서비스를 호스트하는 IIS 웹 사이트의 기본 ID를 구성합니다. 예를 들어 팜 내에 www.contoso.com 있는 컴퓨터는 *:80:www.contoso.com for HTTP and *:443:www.contoso.com for HTTPSIIS 사이트 바인딩을 사용해야 합니다.

IIS MMC(Microsoft Management Console) 스냅인을 사용하여 IIS 웹 사이트 바인딩을 구성할 수 있습니다.

다른 사용자 컨텍스트에서 실행되는 애플리케이션 풀은 임시 폴더의 다른 계정에서 어셈블리를 덮어씁니다.

다른 사용자 컨텍스트에서 실행되는 애플리케이션 풀이 임시 ASP.NET 파일 폴더의 다른 계정에서 어셈블리를 덮어쓸 수 없도록 하려면 다른 애플리케이션에 다른 ID 및 임시 폴더를 사용합니다. 예를 들어 두 개의 가상 애플리케이션 /Application1 및/Application2가 있는 경우 두 개의 서로 다른 ID를 사용하여 두 개의 애플리케이션 풀인 A와 B를 만들 수 있습니다. 애플리케이션 풀 A는 한 사용자 ID(user1)에서 실행할 수 있고, 애플리케이션 풀 B는 다른 사용자 ID(user2)에서 실행되고 A 및 /Application2를 사용하여 B를 사용하도록 /Application1을 구성할 수 있습니다.

Web.config에서 <system.web/compilation/@tempFolder>를 사용하여 임시 폴더를 구성할 수 있습니다. /Application1의 경우 "c:\tempForUser1"일 수 있으며 application2의 경우 "c:\tempForUser2"일 수 있습니다. 두 ID에 대해 이러한 폴더에 해당하는 쓰기 권한을 부여합니다.

그런 다음 user2는 /application2의 코드 생성 폴더를 변경할 수 없습니다(c:\tempForUser1 아래).

비동기 처리 활성화

기본적으로 IIS 6.0 이하에서 호스트되는 WCF 서비스로 전송되는 메시지는 동기 방식으로 처리됩니다. ASP.NET 자체 스레드(ASP.NET 작업자 스레드)에서 WCF를 호출하고 WCF는 다른 스레드를 사용하여 요청을 처리합니다. WCF는 처리를 완료할 때까지 ASP.NET 작업자 스레드를 유지합니다. 이로 인해 요청이 동기 처리됩니다. 요청을 비동기적으로 처리하면 요청을 처리하는 데 필요한 스레드 수가 줄어들기 때문에 확장성이 향상됩니다. 요청을 처리하는 동안 WCF는 ASP.NET 스레드를 유지하지 않습니다. 서버를 DOS( 서비스 거부 ) 공격으로 여는 들어오는 요청을 제한할 방법이 없으므로 IIS 6.0을 실행하는 컴퓨터에는 비동기 동작을 사용하지 않는 것이 좋습니다. IIS 7.0부터 동시 요청 스로틀이 도입되었습니다 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0]"MaxConcurrentRequestsPerCpu. 이 새로운 스로틀을 사용하면 비동기 처리를 사용하는 것이 안전합니다. 기본적으로 IIS 7.0에서는 비동기 처리기 및 모듈이 등록됩니다. 이 기능을 해제한 경우 애플리케이션의 Web.config 파일에서 요청을 수동으로 비동기적으로 처리하도록 설정할 수 있습니다. 사용하는 설정은 설정에 aspNetCompatibilityEnabled 따라 달라집니다. aspNetCompatibilityEnabled이(가) false인 경우, 다음 구성 코드 조각에 표시된 대로 System.ServiceModel.Activation.ServiceHttpModule을(를) 설정하십시오.

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
  </system.serviceModel>  
  <system.webServer>  
    <modules>  
      <remove name="ServiceModel"/>  
      <add name="ServiceModel"
           preCondition="integratedMode,runtimeVersionv2.0"
           type="System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel,Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>  
    </modules>  
    </system.webServer>  

aspNetCompatibilityEnabledtrue로 설정되어 있다면, System.ServiceModel.Activation.ServiceHttpHandlerFactory을(를) 다음 구성 코드 조각에 표시된 대로 구성하십시오.

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>  
  <system.webServer>  
    <handlers>  
          <clear/>  
          <add name="TestAsyncHttpHandler"
               path="*.svc"
               verb="*"
               type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
               />  
    </handlers>
  </system.webServer>  

참고하십시오