이 항목에서는 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 데이터베이스와 동기화하려면 먼저 몇 가지 단계를 완료해야 합니다.
동기화를 위해 SQL Azure 데이터베이스를 프로비전합니다. 이렇게 하면 동기화하는 데 필요한 추적 테이블과 저장 프로시저가 데이터베이스에 만들어집니다. 이는 관리 태스크이므로 Windows Azure 서비스에 포함하지 않아도 됩니다. 대신 Sync Framework 프로비전 방법을 통해 컴퓨터의 SQL Azure 데이터베이스에 연결하여 데이터베이스를 프로비전할 수 있습니다. SQL Azure 데이터베이스를 프로비전하는 방법에 대한 예제는 방법: SQL Azure와의 동기화 구성 및 실행을 참조하십시오.
Windows Azure 서비스 인터페이스를 정의합니다. 이 인터페이스를 구현하고 Windows Azure 웹 역할에서 실행되고 SqlSyncProvider 개체를 호출하여 동기화 태스크를 수행하는 구성 요소를 만듭니다. 로컬 컴퓨터에서 실행되고 Windows Azure 서비스와 통신하는 프록시 공급자를 만듭니다.
Windows Azure에서 호스팅하는 서비스에 Sync Framework 구성 요소를 비롯한 서비스 응용 프로그램을 배포합니다.
로컬 데이터베이스 공급자를 프록시 공급자에 연결하고 동기화합니다.
서비스 인터페이스 및 프록시 공급자 정의 및 구현
N계층 아키텍처에서 Windows Azure가 호스팅하는 서비스는 로컬 컴퓨터의 프록시 공급자와 SQL Azure 데이터베이스 간에 통신하는 중간 계층입니다. 프록시 공급자가 서비스 응용 프로그램과 통신하는 방식은 Windows Azure가 호스팅하는 서비스에서 SqlSyncProvider 데이터베이스 공급자를 호출하는 서비스 응용 프로그램 구성 요소 구현 및 프록시 공급자 구현처럼 사용자가 정의합니다. 이러한 구성 요소의 일반적인 디자인은 다음과 같습니다.
GetChangeBatch 및 ProcessChangeBatch와 같이 동기화에 필요한 모든 메서드를 포함하는 WCF(Windows Communication Foundation) 서비스 계약 인터페이스를 정의합니다.
서비스 계약 메서드를 구현하고 SQL Azure 데이터베이스에서 동작할 SqlSyncProvider 개체를 호출하는 구성 요소를 만듭니다.
이 구성 요소 및 필요한 Sync Framework 구성 요소를 Windows Azure에서 호스팅하는 서비스의 웹 역할에 배포합니다. 사용자의 응용 프로그램에 대한 처리를 일부 수행하고 사용자의 웹 역할로 구성 요소와 직접 통신하는 작업자 역할을 만들도록 결정할 수도 있습니다. 이러한 구성 요소도 지금 배포하십시오.
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 구성 요소를 전용 어셈블리로 사용하도록 설정하려면 다음 단계를 수행합니다.
로컬 컴퓨터에 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입니다.
응용 프로그램에서 사용하는 관리되는 Sync Framework 어셈블리를 서비스 응용 프로그램 어셈블리가 포함된 폴더에 복사합니다. Sync Framework 어셈블리는 Windows Azure 서버의 전역 어셈블리 캐시에 있지 않으므로 .NET Framework는 응용 프로그램 어셈블리가 있는 폴더에서 해당 어셈블리를 검색합니다. 데이터베이스 동기화에 사용되는 관리되는 어셈블리는 다음과 같습니다.
Microsoft.Synchronization.dll
Microsoft.Synchronization.Data.dll
Microsoft.Synchronization.Data.SqlServer.dll
서비스 응용 프로그램의 응용 프로그램 루트 폴더에서 “synchronization.assemblies”라는 폴더를 만듭니다. Sync Framework 설치 폴더에서 응용 프로그램에 필요한 관리되지 않는 어셈블리를 synchronization.assemblies 폴더에 복사합니다. 데이터베이스 동기화에 사용되는 관리되지 않는 어셈블리는 다음과 같습니다.
- Synchronization21.dll
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를 참조하십시오.
런타임에 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이제 Windows Azure에 응용 프로그램을 배포할 준비가 되었습니다.
Windows Azure에 응용 프로그램을 배포하는 방법에 대한 자세한 내용은 Deploying a Service를 참조하십시오.
보안 정보