Windows Azure에서 WCF를 적용할 때 발생하는 문제에 대한 트러블 슈팅

최근 Windows Azure 위에서 사용하기 위하여 WCF 서비스를 테스트하던 중, 이전에 Windows Azure SDK에서 소개했던 문제점을 발견하게되었습니다. IIS에 의하여 호스팅되는 WCF 서비스를 클라우드 밖의 환경에서 참조하기 위하여 프록시 클래스를 생성할 때, Windows Azure의 외부 호스트 주소가 아닌 VM의 로컬 주소를 기준으로 프록시 클래스가 생성되는 현상으로, On-Premise 환경과 달리 Windows Azure Platform의 네트워크 인프라가 로드밸런서에 의하여 동적으로 관리된다는 데에 문제의 핵심이 있습니다.


 


이미 지난 2월에 Windows Azure SDK를 발표하면서 이에 관한 패치 (KB971842 / KB977420)가 같이 소개되었습니다만 이를 실제로 Windows Azure Application에 적용하는 방법에 대한 문서를 써볼 필요가 있어서 늦게나마 이를 올려봅니다. 이 패치는 개발자 컴퓨터에 직접 설치하는 패치로, 이 패치를 통하여 변경되는 사항은 Windows Azure VM 내에도 적용되어있는 상태입니다.


 


1. 패치 설치하기


 


Windows Vista 및 Windows Server 2008에서 Windows Azure SDK를 이용하여 개발하실 경우, http://code.msdn.microsoft.com/KB971842 에서 패치를 다운로드하여 설치하여 주시고, Windows 7 및 Windows Server 2008 R2에서 Windows Azure SDK를 이용하여 개발하실 경우 http://code.msdn.microsoft.com/KB977420 에서 패치를 다운로드하여 설치하여 주시기 바랍니다. (기술 지원 문서는 각각 http://support.microsoft.com/kb/971842 와 http://support.microsoft.com/kb/977420 의 내용을 참조하여 주십시오.)


 


2. Windows Azure Web Role / Worker Role에 Custom Behavior 추가하기


 


기존의 Windows Azure Web Role이나 Worker Role의 WCF 설정 섹션 (system.serviceModel 요소) 아래에 다음과 같은 설정을 추가합니다.


 


    <behaviors>
      <serviceBehaviors>
        <behavior name=”LoadBalancedBehavior“>
          <serviceMetadata httpGetEnabled=”true” />
          <serviceDebug includeExceptionDetailInFaults=”true” />
          <useRequestHeadersForMetadataAddress>
            <defaultPorts>
              <add scheme=”http” port=”81″ />
              <add scheme=”https” port=”444″ />
            </defaultPorts>
          </useRequestHeadersForMetadataAddress>

        </behavior>
      </serviceBehaviors>
    </behaviors>


 


위에서 강조 표시한 부분이 KB971842와 KB977420을 통하여 제공되는 업데이트를 활성화하는데에 필요한 요소입니다. useRequestHeadersForMetadataAddress 요소는 Behavior 이름이 LoadBalancedBehavior라는 설정에 한정되어 유효한 태그이며, 그 이외의 경우는 잘못된 Child 요소로 분류되어 프로그램 수준에서 오류가 발생합니다. 그리고 위의 설정은 Windows Azure Simulator나 Windows Azure Host Process에서만 제대로 동작하며 직접 IIS로 호스팅하는 경우에는 설정이 반영되지 않습니다.


 


만약 기존에 사용하는 별도의 Behavior 설정이 있었다면 기존 Behavior 설정은 유지하시고, LoadBalancedBehavior 설정에 추가하기를 원하는 부분만 복사하여 그대로 붙여넣으면 온전하게 반영됩니다.


 


3. WCF 서비스에 Behavior 연결하기


 


    <services>
      <service behaviorConfiguration=”LoadBalancedBehavior” name=”PhoneNUse.WebRole.PhoneNUse”>
        <endpoint address=”” binding=”basicHttpBinding” contract=”PhoneNUse.WebRole.IPhoneNUse” bindingConfiguration=”PhoneNUse.WebRole.IPhoneNUse”>
          <identity>
            <dns value=”localhost” />
          </identity>
        </endpoint>
        <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
      </service>
    </services>


 


위에서 굵은 표시로 강조한 부분의 속성 값, 즉 behaviorConfiguration 부분만 위에서 지정한 Custom Behavior의 이름인 LoadBalancedBehavior로 변경해주면 서비스에서의 설정은 끝이 납니다.


 


4. 실버라이트를 고려하는 경우


 


실버라이트 컨텐츠를 클라이언트로 사용하는 경우, Windows Azure가 아닌 경우에도 해당이 되지만, Windows Azure에서 WCF를 호스팅할 때에도 동일하게 적용되는 부분이 있습니다. 바로 WCF 서비스의 바인딩 형태에 관한 것과 Cross Domain에 관한 부분입니다.


 


    <services>
      <service behaviorConfiguration=”LoadBalancedBehavior” name=”PhoneNUse.WebRole.PhoneNUse”>
        <endpoint address=”” binding=”basicHttpBinding” contract=”PhoneNUse.WebRole.IPhoneNUse” bindingConfiguration=”PhoneNUse.WebRole.IPhoneNUse”>
          <identity>
            <dns value=”localhost” />
          </identity>
        </endpoint>
        <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
      </service>
    </services>


    <bindings>
      <basicHttpBinding>
        <binding name=”PhoneNUse.WebRole.IPhoneNUse”>
          <security mode=”None” />
        </binding>
      </basicHttpBinding>
    </bindings>


 


위에서 강조 표시한 부분이 실버라이트와의 통신을 고려한 BasicHttpBinding에 대한 설정이 되겠습니다. 그리고 아래의 XML 파일이 clientaccesspolicy.xml 파일이며 보통 Windows Azure Web Role Root에 배치됩니다.


 


<?xml version=”1.0″ encoding=”utf-8″ ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers=”“>
        <domain uri=”
“/>
      </allow-from>
      <grant-to>
        <resource path=”/” include-subpaths=”true”/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>


 


5. 주소 필터 불일치로 인한 문제 해결하기


 


Windows Azure에서 실행되는 WCF 서비스의 경우, 주소 필터 불일치로 인한 문제 때문에 역시 프록시 클래스를 이용한 통신에서 실패할 수 있는데, 이를 방지하기 위한 목적으로 주소 필터의 설정을 완화하는 Attribute를 선언적으로 클래스 앞에 붙일 수 있습니다. 다음의 코드가 그 예시입니다.


 


    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
    public class PhoneNUse : IPhoneNUse
    {
        ….


    }


 


그 외에 좀 더 자세한 내용, 상세한 설정 방법 등은 http://code.msdn.microsoft.com/wcfazure/Wiki/View.aspx?title=KnownIssues 에 게시되어있는 글을 참조하시면 많은 도움이 될 것입니다.


 


감사합니다.

댓글 남기기