다음을 통해 공유


방법: Windows Azure에 Sync Framework 배포

이 항목에서는 Windows Azure에서 호스팅하는 서비스에 Sync Framework 구성 요소를 배포하는 방법을 보여 줍니다. 또한 SQL Azure 데이터베이스와 다른 컴퓨터의 SQL Server 데이터베이스 간에 데이터를 동기화하는 N계층 응용 프로그램을 만드는 방법에 대한 제안 사항도 포함하고 있습니다.

SQL Azure 동기화 이해

SQL Azure Database에 데이터를 저장하면 인터넷에 연결할 수 있는 컴퓨터에서 사용자의 데이터에 안전하게 액세스하는 등 많은 혜택을 누릴 수 있습니다. 그러나 느리거나 불안정한 네트워크를 사용해야 하는 경우도 있습니다. Sync Framework를 사용하여 SQL Azure 데이터베이스와 로컬 컴퓨터의 SQL Server 데이터베이스 간에 데이터를 동기화하면 인터넷의 데이터가 아닌 로컬 컴퓨터의 데이터를 사용할 수 있습니다. 따라서 네트워크 트래픽이 줄어들어 데이터 액세스의 안정성이 높아질 뿐 아니라 네트워크 연결 없이도 작업할 수 있으며 SQL Azure 데이터베이스에 맞게 로컬 데이터베이스가 최신 상태로 유지됩니다.

대개 2계층 아키텍처 또는 N계층 아키텍처라는 두 가지 방법을 사용하여 SQL Server 데이터베이스를 SQL Azure 데이터베이스와 동기화하는 응용 프로그램을 구성할 수 있습니다.

  • 2계층 아키텍처: Sync Framework가 로컬 컴퓨터에서 실행되고 다른 SQL Server 데이터베이스와 마찬가지로 SqlSyncProvider 개체를 사용하여 SQL Azure 데이터베이스에 연결합니다. 이를 수행하는 방법에 대한 자세한 내용은 방법: SQL Azure와의 동기화 구성 및 실행을 참조하십시오.

  • N계층 아키텍처: Sync Framework 데이터베이스 공급자가 Windows Azure에서 호스팅하는 서비스에서 실행되고 로컬 컴퓨터에서 실행되는 프록시 공급자와 통신합니다. 동기화 응용 프로그램은 로컬 컴퓨터에서 실행되고, 로컬 데이터베이스를 나타내는 데이터베이스 공급자를 Windows Azure 서비스와 통신하는 프록시 공급자에 연결합니다. Windows Azure 서비스는 주로 Windows Azure 웹 역할 또는 작업자 역할에서 실행되고 SQL Azure 데이터베이스를 나타내는 SqlSyncProvider 데이터베이스 공급자로 구성됩니다.

동기화 아키텍처에 대한 자세한 내용은 데이터베이스 동기화에 대한 아키텍처 및 클래스를 참조하십시오.

SQL Azure 데이터 동기화 준비

SQL Azure 데이터베이스와 동기화하려면 먼저 몇 가지 단계를 완료해야 합니다.

  1. 동기화를 위해 SQL Azure 데이터베이스를 프로비전합니다. 이렇게 하면 동기화하는 데 필요한 추적 테이블과 저장 프로시저가 데이터베이스에 만들어집니다. 이는 관리 태스크이므로 Windows Azure 서비스에 포함하지 않아도 됩니다. 대신 Sync Framework 프로비전 방법을 통해 컴퓨터의 SQL Azure 데이터베이스에 연결하여 데이터베이스를 프로비전할 수 있습니다. SQL Azure 데이터베이스를 프로비전하는 방법에 대한 예제는 방법: SQL Azure와의 동기화 구성 및 실행을 참조하십시오.

  2. Windows Azure 서비스 인터페이스를 정의합니다. 이 인터페이스를 구현하고 Windows Azure 웹 역할에서 실행되고 SqlSyncProvider 개체를 호출하여 동기화 태스크를 수행하는 구성 요소를 만듭니다. 로컬 컴퓨터에서 실행되고 Windows Azure 서비스와 통신하는 프록시 공급자를 만듭니다.

  3. Windows Azure에서 호스팅하는 서비스에 Sync Framework 구성 요소를 비롯한 서비스 응용 프로그램을 배포합니다.

  4. 로컬 데이터베이스 공급자를 프록시 공급자에 연결하고 동기화합니다.

서비스 인터페이스 및 프록시 공급자 정의 및 구현

N계층 아키텍처에서 Windows Azure가 호스팅하는 서비스는 로컬 컴퓨터의 프록시 공급자와 SQL Azure 데이터베이스 간에 통신하는 중간 계층입니다. 프록시 공급자가 서비스 응용 프로그램과 통신하는 방식은 Windows Azure가 호스팅하는 서비스에서 SqlSyncProvider 데이터베이스 공급자를 호출하는 서비스 응용 프로그램 구성 요소 구현 및 프록시 공급자 구현처럼 사용자가 정의합니다. 이러한 구성 요소의 일반적인 디자인은 다음과 같습니다.

  1. GetChangeBatchProcessChangeBatch와 같이 동기화에 필요한 모든 메서드를 포함하는 WCF(Windows Communication Foundation) 서비스 계약 인터페이스를 정의합니다.

  2. 서비스 계약 메서드를 구현하고 SQL Azure 데이터베이스에서 동작할 SqlSyncProvider 개체를 호출하는 구성 요소를 만듭니다.

  3. 이 구성 요소 및 필요한 Sync Framework 구성 요소를 Windows Azure에서 호스팅하는 서비스의 웹 역할에 배포합니다. 사용자의 응용 프로그램에 대한 처리를 일부 수행하고 사용자의 웹 역할로 구성 요소와 직접 통신하는 작업자 역할을 만들도록 결정할 수도 있습니다. 이러한 구성 요소도 지금 배포하십시오.

  4. KnowledgeSyncProvider를 구현하고 로컬 컴퓨터에서 실행되고 Windows Azure에서 호스팅하는 서비스가 구현하는 서비스 인터페이스를 호출하는 프록시 공급자를 만듭니다.

서비스 인터페이스와 프록시 공급자를 구현하는 것은 매우 복잡합니다. WCF를 사용하여 Windows Azure에서 호스팅하는 서비스와 통신하고 SQL Azure 데이터베이스와 동기화하는 동기화 응용 프로그램의 예를 보려면 Code Gallery를 참조하십시오.

Windows Azure에 Sync Framework 구성 요소 배포

Windows Azure에서 호스팅하는 서비스 응용 프로그램은 Sync Framework 구성 요소를 전용 어셈블리로 사용합니다. 따라서 서비스 응용 프로그램은 해당 사용자에게 필요한 Sync Framework 구성 요소 집합만 사용하고, 다른 응용 프로그램에서 사용하는 Sync Framework 구성 요소의 영향을 받지 않습니다. 서비스 응용 프로그램에서 Sync Framework 전용 어셈블리를 사용하도록 설정한 후에는 호스팅되는 서비스를 Windows Azure에 배포할 때와 동일한 방법으로 응용 프로그램을 배포하면 됩니다.

보안 정보보안 정보

전용 어셈블리는 자동 보안 업데이트를 받지 못하므로 서비스 소유자가 Sync Framework 구성 요소의 모든 필수 업데이트를 설치해야 합니다.

서비스 응용 프로그램이 Sync Framework 구성 요소를 전용 어셈블리로 사용하도록 설정하려면 다음 단계를 수행합니다.

  1. 로컬 컴퓨터에 Sync Framework 2.1 SDK를 설치합니다. SDK는 MSDN Sync Framework Developer Center에 있습니다. x64 플랫폼에서 Sync Framework 2.1 어셈블리의 기본 설치 폴더는 C:\Program Files\Microsoft SDKs\Microsoft Sync Framework\2.1\Runtime\x64입니다.

  2. 응용 프로그램에서 사용하는 관리되는 Sync Framework 어셈블리를 서비스 응용 프로그램 어셈블리가 포함된 폴더에 복사합니다. Sync Framework 어셈블리는 Windows Azure 서버의 전역 어셈블리 캐시에 있지 않으므로 .NET Framework는 응용 프로그램 어셈블리가 있는 폴더에서 해당 어셈블리를 검색합니다. 데이터베이스 동기화에 사용되는 관리되는 어셈블리는 다음과 같습니다.

    • Microsoft.Synchronization.dll

    • Microsoft.Synchronization.Data.dll

    • Microsoft.Synchronization.Data.SqlServer.dll

  3. 서비스 응용 프로그램의 응용 프로그램 루트 폴더에서 “synchronization.assemblies”라는 폴더를 만듭니다. Sync Framework 설치 폴더에서 응용 프로그램에 필요한 관리되지 않는 어셈블리를 synchronization.assemblies 폴더에 복사합니다. 데이터베이스 동기화에 사용되는 관리되지 않는 어셈블리는 다음과 같습니다.

    • Synchronization21.dll
  4. Sync Framework는 COM을 사용하여 관리되지 않는 어셈블리를 로드합니다. 일반적으로 COM은 레지스트리를 사용하여 어셈블리를 찾습니다. Windows Azure의 레지스트리를 사용하는 대신 COM에서 관리되지 않는 전용 어셈블리를 찾을 수 있도록 두 개의 매니페스트 파일을 포함하십시오.

    synchronization.assemblies 폴더에 “synchronization.assemblies.manifest”라는 텍스트 파일을 만들어 첫 번째 매니페스트 파일을 만듭니다. 이 파일에 다음 정보를 복사합니다.

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
    <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
    
    <assemblyIdentity
       type="x64"
       name="synchronization.assemblies"
       version="2.1.0.0"
    />
    
      <file name = "synchronization21.dll">
        <comClass clsid="{EC413D66-6221-4ebb-AC55-4900FB321011}" threadingModel="Both"/>    
      </file>
    
    </assembly>
    

    응용 프로그램 루트 폴더에 “webapp.manifest”라는 텍스트 파일을 만들어 나머지 매니페스트 파일을 만듭니다. 이 파일에 다음 정보를 복사합니다.

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    
      <assemblyIdentity name="webapp" version="8.0.0.0" type="x64"/>
    
      <dependency>
        <dependentAssembly>
    
          <assemblyIdentity name="synchronization.assemblies" version="2.1.0.0" type="x64"/>
        </dependentAssembly>
      </dependency>
    
    
    </assembly>
    

    전용 COM 어셈블리에 대한 자세한 내용은 Isolated Applications and Side-by-Side Assemblies를 참조하십시오.

  5. 런타임에 COM 어셈블리를 로드하는 데 사용되는 활성화 컨텍스트를 응용 프로그램에 만듭니다. 이렇게 하려면 프로젝트에 다음과 같은 클래스를 만들고 응용 프로그램이 시작될 때 Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart 메서드를 재정의하는 등의 방법으로 CreateActivationContext 메서드를 호출합니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Runtime.InteropServices;
    using System.IO;
    
    namespace Microsoft.Samples.Synchronization
    {
        public class ActivationContext
        {
            // Activation Context API Functions 
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            private extern static IntPtr CreateActCtx(ref ACTCTX actctx);
    
            // Activation context structure 
            private struct ACTCTX
            {
                public int cbSize;
                public uint dwFlags;
                public string lpSource;
                public ushort wProcessorArchitecture;
                public ushort wLangId;
                public string lpAssemblyDirectory;
                public string lpResourceName;
                public string lpApplicationName;
            }
    
            private const int ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004;
            private const int ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x00000010;
            private IntPtr m_hActCtx = (IntPtr)0;
            public const UInt32 ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET = 14011;
    
            /// <summary>
            /// Explicitly load a manifest and create the process-default activation 
            /// context. It takes effect immediately and stays there until the process exits. 
            /// </summary>
            static public void CreateActivationContext()
            {
                string rootFolder = AppDomain.CurrentDomain.BaseDirectory;
                string manifestPath = Path.Combine(rootFolder, "webapp.manifest");
                UInt32 dwError = 0;
    
                // Build the activation context information structure 
                ACTCTX info = new ACTCTX();
                info.cbSize = Marshal.SizeOf(typeof(ACTCTX));
                info.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT;
                info.lpSource = manifestPath;
                if (null != rootFolder && "" != rootFolder)
                {
                    info.lpAssemblyDirectory = rootFolder;
                    info.dwFlags |= ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
                }
    
                dwError = 0;
    
                // Create the activation context 
                IntPtr result = CreateActCtx(ref info);
                if (-1 == result.ToInt32())
                {
                    dwError = (UInt32)Marshal.GetLastWin32Error();
                }
    
                if (-1 == result.ToInt32() && ActivationContext.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET != dwError)
                {
                    string err = string.Format("Cannot create process-default win32 sxs context, error={0} manifest={1}", dwError, manifestPath);
                    ApplicationException ex = new ApplicationException(err);
                    throw ex;
                }
            }
        }
    }
    
    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.Web
    Imports System.Runtime.InteropServices
    Imports System.IO
    
    Namespace Microsoft.Samples.Synchronization
        Public Class ActivationContext
            ' Activation Context API Functions 
    
            <DllImport("Kernel32.dll", SetLastError := True)> _ 
            Private Shared Function CreateActCtx(ByRef actctx As ACTCTX) As IntPtr
            End Function
    
            ' Activation context structure 
            Private Structure ACTCTX
                Public cbSize As Integer
                Public dwFlags As UInteger
                Public lpSource As String
                Public wProcessorArchitecture As UShort
                Public wLangId As UShort
                Public lpAssemblyDirectory As String
                Public lpResourceName As String
                Public lpApplicationName As String
            End Structure
    
            Private Const ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID As Integer = &H4
            Private Const ACTCTX_FLAG_SET_PROCESS_DEFAULT As Integer = &H10
            Private m_hActCtx As IntPtr = DirectCast(0, IntPtr)
            Public Const ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET As UInt32 = 14011
    
            ''' <summary>
            ''' Explicitly load a manifest and create the process-default activation 
            ''' context. It takes effect immediately and stays there until the process exits. 
            ''' </summary>
            Public Shared Sub CreateActivationContext()
                Dim rootFolder As String = AppDomain.CurrentDomain.BaseDirectory
                Dim manifestPath As String = Path.Combine(rootFolder, "webapp.manifest")
                Dim dwError As UInt32 = 0
    
                ' Build the activation context information structure 
                Dim info As New ACTCTX()
                info.cbSize = Marshal.SizeOf(GetType(ACTCTX))
                info.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT
                info.lpSource = manifestPath
                If rootFolder IsNot Nothing AndAlso "" <> rootFolder Then
                    info.lpAssemblyDirectory = rootFolder
                    info.dwFlags = info.dwFlags Or ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID
                End If
    
                dwError = 0
    
                ' Create the activation context 
                Dim result As IntPtr = CreateActCtx(info)
                If -1 = result.ToInt32() Then
                    dwError = DirectCast(Marshal.GetLastWin32Error(), UInt32)
                End If
    
                If -1 = result.ToInt32() AndAlso ActivationContext.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET <> dwError Then
                    Dim err As String = String.Format("Cannot create process-default win32 sxs context, error={0} manifest={1}", dwError, manifestPath)
                    Dim ex As New ApplicationException(err)
                    Throw ex
                End If
            End Sub
        End Class
    End Namespace
    
  6. 이제 Windows Azure에 응용 프로그램을 배포할 준비가 되었습니다.

    Windows Azure에 응용 프로그램을 배포하는 방법에 대한 자세한 내용은 Deploying a Service를 참조하십시오.

참고 항목

개념

SQL Server와 SQL Server Compact 동기화