Windows Azure Platform의 핵심 구성 요소들 중 하나인 Windows Azure Storage가 이번 BUILD Windows 2011 행사 이튿날에 발표한 기능 중에는 Windows Azure Storage의 향상에 관한 내용이 있었는데, 그 동안 Windows Azure Storage에 대해서 바라던 많은 요구 사항들이 이번에도 성실하게 반영되었습니다. 그 중에서도 큰 맥락을 나누면 같은 지역 내의 다른 데이터센터로 Storage의 데이터를 복제할 수 있는 Geo-Replication 기능과, BLOB, Table, Queue 스토리지의 사용법 개선에 따른 성능 향상이 있습니다.
Geo-Replication
이제 Windows Azure Storage 역시 다른 Cloud Platform들과 마찬가지로 재해 복구 기능을 가질 수 있게 되었습니다. 기존에는 Geo-Replication을 전적으로 이용자의 재량으로 해야했고, 비용 투자가 필요했던 부분이지만 이 기능을 네이티브하게 지원할 수 있게 되었기 때문에 더 안전한 서비스 사용이 가능해지게 되었습니다. Geo-Replication은 Windows Azure BLOB과 Table 스토리지에 한정되는 내용으로 예를 들어 북유럽과 서유럽 사이, 동아시아와 동남아시아 사이의 데이터센터 간에 데이터 복제를 수행하여 Redundancy를 확보하는 전략입니다. 그러나 아시아와 유럽 간 복제는 수행하지 않으며, 모든 작업은 비동기적으로 수행되므로 현재 서비스에서 변경되거나 영향을 주는 부분은 없다고 합니다.
새 BLOB, Table 및 Queue 스토리지의 기능들
2011-08-18 버전의 REST API에서는 기존에 커뮤니티로부터 많은 요청이 있었던 기능들을 제공하는데, 다음과
Table Upsert: 한 번의 요청으로 이미 존재하는 엔터티에 대해서는 업데이트를, 존재하지 않는 엔터티에 대해서는 삽입을 조건부로 처리할 수 있는 기능입니다.
Projection Query 지원: 엔터티의 하위 집합을 만들 수 있는 기능으로 LINQ to Table Storage 등에 직접적인 영향을 주게 될 가장 큰 기능입니다. 이전에는 Projection Query를 수행할 수 없었기 때문에 전체 엔터티 컬렉션을 서버로부터 우선 다운로드한 다음 이것을 메모리에서 정리하는 비효율적인 방식을 사용했지만 이 작업을 서버 차원에서 직접 수행할 수 있게 됨에 따라 대역폭 사용량을 줄이고 쿼리 성능을 더 업그레이드할 수 있게 되었습니다.
향상된 BLOB HTTP 헤더 지원: BLOB 차원의 동영상 스트리밍이 가능해지고, 다운로드 가속기 등으로 이어받는 작업이 가능해졌습니다.
큐 메시지 업데이트: 큐에 삽입한 메시지의 내용을 편집하거나, 유효 기한을 연장하여 큐 자체의 항목을 엔터티로 취급할 수 있게 하고 길게 소요되는 작업에 대한 이벤트 처리를 큐 스토리지를 통해서 할 수 있도록 기능을 보강했습니다.
큐 메시지 삽입 시 대기 시간 지정: 큐에 메시지를 삽입한 직후에 다른 큐 메시지 수신처에서 내용을 보이게 하지 않고, 지정된 기간 동안 내용을 숨기도록 삽입할 수 있습니d
Windows Azure Cafe (http://cafe.naver.com/wazure)에서는 지난해에 이어 올해부터는 매월 다양한 주제를 통하여 개발자, IT 전문가들에게 Windows Azure 기반의 실전 개발에 대한 이야기를 전할 수 있또록 Boot Camp 세미나를 준비하였습니다. 클라우드 컴퓨팅에 관심이 있는 분들을 모시고, 세미나 전/후로는 클라우드 컴퓨팅과 최신 기술 동향에 대한 자유로운 토론도 같이 진행할 수 있도록 하겠습니다. 제목: 기존 소프트웨어에서 Windows Azure를 활용하는 방법 일시: 2011년 7월 2일 토요일 / 오후 2시 장소: 포스코센터 서관 5층 한국 마이크로소프트 GROW룸 대상: 소프트웨어, 웹 개발자 세션 소개 (1) Windows Azure Storage 활용 전략 Windows Azure Storage는 익히 알려진대로 세 가지의 대표적인 저장소 (테이블, BLOB, 큐)를 이용하여 개발할 수 있는 것이 특징입니다. 그러나 이들 저장소는 우리가 기존에 알고 있던 파일 시스템이나 관계형 데이터베이스와는 전혀 다른 시스템들입니다. 이러한 시스템들을 어떻게 효과적으로 사용할 수 있는지에 대해 알아보도록 하겠습니다. - Windows Azure Storage 및 주요 기능 소개 - Storage를 중심으로 활용하는 몇 가지 유용한 모델에 대한 소개 (2) .NET 클라이언트 및 웹 개발자들을 위한 활용 전략 Windows Azure Storage를 .NET 클라이언트 개발 환경에서는 어떻게 활용할 수 있는지 클라이언트 및 웹 개발자들의 관점에서 유용한 정보를 알려드리도록 하겠습니다. - Windows Azure Storage 라이브러리를 활용하는 방법 - 관계형 데이터베이스가 아니라는 것이 끼칠수 있는 문제점들 - LINQ to Table Storage에 대한 몇 가지 이슈 아젠다 14:00 ~ 14:50 (1) Windows Azure Storage 활용 전략 14:50 ~ 15:00 휴식 15:00 ~ 15:50 (2) .NET 클라이언트 및 웹 개발자들을 위한 활용 전략 15:50 ~ 16:00 질문/답변 시간, 장소, 날짜 일시: 2011년 6월 25일 토요일 / 오후 2시 장소: 포스코센터 서관 5층 한국 마이크로소프트 (ROOM은 추후 확정 후 다시 공지하겠습니다.) 알립니다: 본 세미나는 커뮤니티가 주최하는 비영리 세미나이며, 주차권은 별도로 제공되지 않으니 가급적 대중 교통을 이용하여 주시면 감사하겠습니다.
뜬금없이 근두운 이야기가 무엇인가 하고 놀라는 분들이 있으리라 생각한다. 이해가 빠른 분들이 계실 것이므로 단도직입적으로 말하면, 필자가 의도한 그대로, Cloud Computing 이야기를 하고자 했던 것이다. 우리의 머릿속 한 구석에 큰 존재감을 과시하며 차지하고 있는 전설 속 원숭이 손오공의 근두운을 IT 세상에서는 누구나 하나씩 다 가지고 있는 것이다.
여러분이 사용하고 싶어하는 근두운의 종류 또한 다양하다. 그래서 앞서 설명했던 Windows Live, Windows Server 기반 Private Cloud, Office 365가 있었고, 오늘은 마지막으로 개발자와 IT 전문가들의 관점에서 적극적으로 검토해 볼 가치가 있고 든든한 파트너 역을 맡아줄 Windows Azure Platform이라는 근두운을 이야기해볼 생각이다.
IT 관리자의 관점에서 보는 Windows Azure Platform
PDC08에서 처음 소개된 Windows Azure Platform은 전적으로 개발자의 역할을 중시했던 플랫폼이었다. 이는 PDC09, 그리고 PDC 2010 직전까지도 지속되었고 꾸준히 그 색을 더해 나가고 있던 과정이었다. 하지만 PDC 2010에서 처음으로 세간에 루머로만 떠돌던 VM Role이 공식적으로 사용 가능하게 베타 서비스로 출시되었고 이에 따라 IT 관리자들의 관점에서도 Windows Azure Platform을 활용할 수 있는 기회가 대폭 늘어나게 되었다.
Windows Azure Platform이 IT 관리자들에게 제공하는 주요 이점은 한 마디로 정리하면 기존의 IT 자산과 맞물려 사용할 수 있는 다양한 기회를 제공한다는 점이다. Microsoft의 Public Cloud는 모든 것을 Cloud로 올려야 한다고 말하지 않는다. 대신, 네트워크 수준에서의 통합부터 시작하여 Cloud 내부 및 외부에서 발생할 수 있는 문제를 다양한 방법으로 해결할 수 있도록 도와준다.
Windows Azure의 VM Role은 On-Premise 시스템을 분리 해체하는 작업을 거치지 않고 곧바로 Windows Azure 데이터센터에 서버를 올려놓는 방법이다. 기존에 먼저 소개된 Web Role 및 Worker Role과 달리 Windows Server 2008 R2 운영 체제 전체를 하나의 완전한 Role로 채택하여 사용할 수 있는 기법으로, 여러분이 기존에 어떤 라이선스를 가지고 있던지 관계없이 Windows Azure VM Role 라이선스로 전환할 수 있도록 해준다.
매우 이상적인 이야기처럼 들릴 수도 있지만 사실 중요한 문제가 두 가지가 있다. 라이선스에 관한 것이 있고, 또 다른 하나는 기술적인 구성 상의 문제이다. 다음의 표에 대략적인 내용을 언급해두었다.
구성 요소 및 역할
변경 방향
3rd Party Software
Plan A: Public Cloud 호환 라이선스로 재계약
Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합 / 단 Traffic 추가로 인한 변동 사항은 해당 공급자와 재 협상 필요
3rd Party Software Data
SQL Server Embedded DB
è MDF 및 LDF 파일을 SQL Server에 연결하고, 해당 DB를 SQL Azure로 이관해야 함
è MDB 파일이나 ACCDB 파일의 경우 SQL Server로 이관 후 SQL Azure로 이관해야 함
기타 데이터베이스
è 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합
SQL Server
Plan A: SQL Azure로 부분/전체 Migration
Plan B: 관계 지향적이지 않고 대용량 DB가 필요한 경우 Windows Azure Table Storage 사용
Plan C: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합
Exchange Server
Plan A: Office 365로 부분/전체 Migration
Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합
SharePoint Online
Plan A: Office 365로 부분/전체 Migration
Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합
Lync Online
Plan A: Office 365로 부분/전체 Migration
Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합
Active Directory
AD DS, AD LDS 모두 기존의 On-Premise 시스템을 Windows Azure Connect를 경유하여 활용하는 것이 최선
라이선스에 관한 문제의 본질은 다음과 같다. Windows Azure Compute를 통해서 서비스가 실행되면, Service Level Agreement (SLA) 계약 이행을 위하여 기본적으로 VM을 1대 이상 사용하는 것을 전제로 한다. 최소 1대만을 유지하도록 설정해도 상관은 없지만, 필연적으로 사용량이 증가하고 서비스를 위하여 배치된 VM들의 상태가 바빠지는 것이 감지되면 자동적으로 Fabric Controller가 원본 VM 이미지를 복제하여 새로운 VM을 복제하기 시작한다. 이것이 의미하는 바는 단순하다. 물리적인 Instance의 수가 자동으로 늘어나므로 그 안에 포함된 3rd Party 소프트웨어에 대한 라이선스도 같이 계산되어야 하고, 그것이 CPU 기반 라이선스이든 연결 개수 기반 라이선스이든 상관이 없는 것이다. 양쪽 라이선스 모두 있는 그대로 (as-is) 해석을 한다면 Public Cloud 내에서는 상식을 넘는 금액을 요구할 수 밖에 없다.
이를 해결하기 위해서는 해당 소프트웨어 공급자가 Public Cloud에 대응되는 사용량 – 또는 – 사용 시간 기반 라이선스를 지원해야 하며, 대다수의 경우 이를 지원하지 않을 것이므로 이러한 소프트웨어를 포함하는 서버를 On-Premise 환경에 배치하고, 이들 서버에 대한 종속성을 지니는 별도의 VM Role, Web Role, Worker Role 만을 Windows Azure에 게시한 후 Windows Azure Connect로 상호 연동을 가능하게 만드는 것이 최선이다.
기술적인 문제의 본질은 다음과 같다. 주로 데이터베이스에 대한 부분과 관련이 깊은데, Windows Azure가 SLA 이행을 위하여 VM을 복제하고, 복제된 VM들의 목록을 기준으로 Load Balancer를 구현하는 것은 매우 바람직한 일이다. 그러나 기존의 서버 모델은 개별 서버가 데이터베이스까지 서버 내에 같이 포함하고 있는 경우가 많은데 여기에 대한 적당한 조치를 취하지 않고 그대로 VM Role로 전환하는 경우 우스꽝스러운 문제가 발생한다. 접속할 때 마다 데이터베이스의 내용이 달라지는 일이 발생하는 것이다. 이를 해결하기 위해서는 사용 중인 데이터베이스의 종류를 파악하는 것이 중요한데, SQL Server로 이관이 가능한 범주 안에 있는 데이터베이스들은 우선 SQL Server로 이관한 후, 이를 SQL Azure로 다시 이관하는 작업이 필요하다. 그리고 기존 응용프로그램들도 SQL Azure를 데이터 소스로 사용할 수 있도록 일부 수정이 필요하다.
SQL Azure로 이관하는 것을 누구나 쉽게 검토해볼 수는 있다. 그러나 생각 외로 만만찮은 문제들이 쌓여있다. 기존에 사용하던 자료 형식 중 CHAR, VARCHAR, TEXT와 같이 유니코드와 호환되지 않는 문자열 자료 형식들은 이관 후 CJK 문자 세트로 구성된 데이터가 소실되므로 NCHAR, NVARCHAR, NTEXT로 업그레이드해야 한다는 부분이 있다. 날짜와 시간의 경우 이관 이전과 이관 이후의 시간대 설정 차이가 있으므로 데이터 일관성에 문제가 있을 수 있다는 점이다. 드문 경우이지만, .NET 어셈블리는 SQL Azure에 설치할 수 없으므로 이와 관련된 기능을 사용하는 경우 SQL Azure로 이관하기 전 적당한 Wrapper나 Agent를 따로 개발해야 한다. 또, 기존의 응용프로그램이 데이터베이스 연결을 헤프게 사용하는 경향이 있다면 SQL Azure 입장에서는 예고 없이 연결을 차단시킬 수 있다는 점도 숙지해야 한다. SQL Azure 서비스 자체는 공유 환경에서 실행되므로 SQL Server 인프라와는 비교할 수 없이 엄격한 정책 준수를 요구하는데, 사실 이 때문에 낭패를 보는 경우가 많다. 이런 모든 문제들을 극복하기 위해서, 데이터베이스 역시 특별한 이슈가 없다면 Windows Azure Connect를 사용하여 기존 On-Premise 환경과 구분선 없이 밀착시키는 것이 좋을 수 있다.
사실 지금 언급한 내용들만 이야기해도 Cloud로 이관하는 것보다는 이관하지 않는 것이 더 좋은 것처럼 들린다. 그래서, IT 관리자 입장에서는 무리해서 기존의 인프라를 Cloud로 이관하기 보다, 기존의 인프라나 IT 자산으로는 충당할 수 없는 새로운 영역을 Cloud를 통해 개발하고 확보하는 방법을 새로 익히는 것이 좋다. 그런 맥락에서, IT 관리자들은 Cloud 환경에 최적화된 VM-Role을 개발하는 방법을 익히고, VM-Role이 Windows Azure Connect를 통하여 기존의 Active Directory Domain Controller에 참가하도록 시스템을 구성하거나, 웹 상에서의 클레임 기반 인증을 구현할 목적으로 Active Directory Federation Services (AD FS)와 Windows Azure AppFabric Access Control을 같이 활용하는 방안을 모색하는 것이 바람직하다.
응용프로그램 개발자 관점에서 보는 Windows Azure
원래부터 그러했지만 Windows Azure는 개발자들을 위한 Cloud 플랫폼이었다. 여러 서비스들이 있지만 각각의 역할을 하나씩 소개하려 한다.
Windows Azure Compute: Windows Azure 데이터센터에서 여러분의 응용프로그램을 Hosting할 수 있도록 해주며, IIS를 활용하여 웹 응용프로그램을 실행할 수 있도록 해주는 Web Role, WCF, Socket, C, C++, Python 등 Win32 기반 시스템에서 사용 가능한 모든 종류의 응용프로그램을 실행할 수 있도록 해주는 Worker Role, 그리고 VHD 기반 이미지를 이용하여 Windows Server 2008 R2 OS를 실행할 수 있도록 해주는 VM Role을 하나의 서비스 안에서 다양한 방법으로 조합하여 실행할 수 있는 서비스이다. Windows Azure SDK에서는 VM Role을 제외한 Web Role과 Worker Role 에뮬레이터가 기본 제공된다.
Windows Azure Storage: 대용량의 데이터를 고속으로 처리할 수 있도록 해주는 특별한 저장소로, HTTP 및 HTTPS 프로토콜을 기반으로 상호 작용할 수 있기 때문에 플랫폼이나 위치에 제약이 없다. 저장소의 유형으로는, 단순 파일 저장 및 대용량 파일의 Paging 연산을 지원하는 BLOB 저장소, 행과 열의 대규모 집합 및 고속 인덱싱을 지원하는 테이블 저장소, 고속 메시지 입력 및 출력을 지원하는 큐 저장소로 구분된다. 저장소의 범주에 속하지는 않으나, Windows Azure Compute 상의 Role들이 Win32 API를 사용하여 파일 입력과 출력 연산을 수행할 수 있도록 해주는 Cloud Drive API가 Windows Azure Storage Emulator와 함께 제공된다.
Windows Azure CDN: 대한민국 및 아시아 권역에서 빠른 속도를 자랑하는 새로운 CDN 서비스 역시 Windows Azure Platform 안에 있다. 기본적으로는 Windows Azure Blob Storage에서 공개 권한으로 설정한 Block BLOB에 대해 CDN 서비스를 사용할 경우 자동으로 Mirroring이 된다. 최근 업데이트에서는 Windows Azure Storage가 아닌, 동적으로 API를 사용하여 특정 Contents를 CDN 서비스를 통해 Mirroring할 수 있게 업데이트되었고, 더불어 HTTPS도 지원하기 시작하였다.
Windows Azure AppFabric: 대규모 서비스 운영에 필요한 주요 서비스 컴포넌트 5가지를 제공하는 온라인 서비스로, Windows Server AppFabric의 기술을 바탕으로 하지만 외부에 드러나는 모습은 많이 다르다.
Windows Azure 초창기부터 지속적으로 제공되어왔던 Service Bus는 Point-to-Point 연결을 구현하는 Tunneling Mechanism을 제공한다. WCF 기술을 기반으로 하며, 서버 역할을 수행하는 WCF 호스트가 Service Bus와 연결을 맺은 뒤, WCF 클라이언트는 직접 WCF 호스트에 접근하지 않는 대신, 암호화된 연결을 사용하는 Service Bus로 방향을 바꾸어 접속을 시도하는 방식이다. 이러한 방식이 유용한 이유는, 방화벽의 존재 여부와 관계없이 네트워크 계층에 일관성이 없는 서로 다른 환경 사이를 완벽하게 연결시켜주기 때문이다.
Access Control 서비스는 또 한 번 업데이트를 준비 중에 있다. 처음 발표된 Access Control은 특정 도메인이나 기관이 운영하는 Active Directory 인프라를 기반으로 인터넷 상에서 클레임 기반 인증을 구현하기 위한 목적으로 처음 소개되었다. 인터넷 서비스를 상대로 클레임 기반 인증을 수행하는 것이기 때문에, 인트라넷 환경과는 달리 수시로 Traffic이 발생하며, 뿐만 아니라 신뢰성도 매우 중요하기 때문에 Azure AppFabric Access Control이 유용하다. 그리고 조만간 대대적인 업데이트를 통하여 Windows Live ID, Yahoo, Google, Facebook 등의 Social Networking Platform을 인증 수단으로 사용할 수 있게 되어 한층 더 폭넓은 활용 가능성을 제공한다.
Cache 서비스는 Server 버전의 AppFabric Cache를 Cloud 버전으로 제공하는 것으로, Cache를 위한 인프라를 직접 구축하지 않으면서, 같은 API, 같은 기술을 사용할 수 있는 것이 장점이다. Windows Azure Storage와 SQL Azure를 AppFabric Cache 원본으로 지정하여 사용할 경우 시간과 비용을 획기적으로 절약할 수 있다. 그리고 올해 연중으로 BizTalk Server와의 연계를 고려한 AppFabric Integration 서비스와 함께 Cloud Computing 전반을 통솔하고 제어할 수 있는 AppFabric Composite App 역시 출시될 예정에 있다.
물론 아직 부족한 서비스들도 있다. 그렇지만 이 정도 수준의 서비스라고 한다면 누구나 원하는 서비스를 제약 없이 구현해 볼 수 있지 않을까? 프로그래밍 언어나 개발 도구에 관계없이, 그리고 여러분이 실행하는 프로그램의 위치와 무관하게 말이다. 다시 강조하지만, Microsoft의 Public Cloud는 다른 Cloud Platform들처럼 강제 이주를 논하지 않는다. 모든 것은 여러분의 결정에 따라 움직이며, 매번 적절한 솔루션은 Microsoft에 의해서이든 오픈 소스 커뮤니티에 의해서이든 쓰여지고 업그레이드되어 나가고 있다. Microsoft가 말하는 Cloud Power의 진가를 확인하고 싶다면 지금 곧 Windows Azure Platform으로 떠나보자.
최근에 저는 Windows Azure Storage를 관리 목적으로 편리하게 활용할 수 있는 유틸리티를 찾아 나섰습니다. 그 동안 소개했던 myazurestorage의 경우 웹 브라우저의 기능 상 한계때문에 큰 파일을 올리거나 복잡한 작업을 하기에는 부족한 부분이 많았습니다. 또한 예제 형태로 제공되던 다양항 유형의 관리 도구들 역시 미약한 부분들이 많았습니다. 그러던 중 가장 사용하기 쉽고 편리하면서도, 기본적인 모든 기능을 무료로 제공하는 멋진 유틸리티 하나를 찾았습니다. 바로 CloudBerry Explorer for Microsoft Azure Storage입니다. 원래는 Amazon S3를 위한 버전을 먼저 출시했던 제품이지만 클라우드와의 상관관계성을 반영하여 Microsoft Azure Storage에 대한 버전도 추가로 출시하였습니다.
기본적으로는 Windows Commander와 유사한 사용자 인터페이스를 가지고 있으며 양쪽을 Side-by-Side로 살펴보면서 탐색할 수 있는 기능을 제공합니다. API를 가지고 작업할 때와는 달리, 적당한 MIME TYPE을 자동으로 유추하여 지정하는 기능도 제공하고, CloudBerry Explorer에서 가장 핵심적인 기능인 동기화 기능을 제공하므로 많은 수의 파일을 업로드할 때 매우 유용하게 사용할 수 있습니다.
아직 Azure Storage의 모든 기능들을 제공하는 것은 아니지만 이 글을 쓰는 시점 이후로 추가될 것으로 예정한 기능들은 다음과 같습니다. 아래와 같은 기능들이 더 추가되면 더 나은 관리 도구로서 거듭날 수 있을 것입니다.
조건부 헤더 설정
접근 권한 목록 (ACL) 편집을 지원
서버 Timeout 지원
컨테이너와 BLOB에 대한 메타데이터 관리 지원
Microsoft PowerShell 연동을 통한 자동화 지원
Azure CDN에 대한 기능 지원
CloudBerry Explorer는 Windows XP 이후부터 사용이 가능하고, Microsoft .NET Framework 2.0 이상이 시스템에 설치되어있어야 합니다. 상용 버전의 경우, 차이점 비교, 고급 동기화 기능 등을 제공하므로 더 복잡한 작업을 수행하기 원하는 경우 소프트웨어 구입을 검토해보시는 것도 괜찮습니다. 무료 버전의 경우 제한 없이 사용 가능하며, http://cloudberrylab.com/?page=explorer-azure 에서 다운로드하실 수 있습니다. :-)
Windows Azure BLOB Storage는 클라우드 기반의 저장소이지만 외부에서 사용하기에 무척 편리하고 유용한 HTTP 및 HTTPS 프로토콜을 기반으로 서비스가 제공됩니다. 대화형 서버 처리 엔진이 존재하지 않는다는 점만 제외하면 HTTP 기반의 서비스를 구축하기 위해서 필요한 모든 사항이 제공되며, 파일 이어받기, ETAG 처리 등 HTTP 프로토콜의 최신 사양들을 정확히 구현하고 있습니다.
최근에 저는 Windows Azure Platform의 Storage Service를 활용하면서 또 한 가지 좋은 정보를 얻을 수 있었습니다. Windows Azure Storage를 사용하면서 가장 필요한 것 중 하나는 RIA 응용프로그램과 충분히 활용하는 전략인데, 여기에는 Smooth Streaming 뿐만 아니라 일상적으로 활용 가능한 이미지, 사운드, 비디오, 텍스트 파일들도 포함될 수 있습니다. 그러나 익히 알려진대로 보안 상의 이유 때문에 RIA 플랫폼 자체적으로는 접근하려는 원격 웹 서버의 루트 경로 상에 반드시 매니페스트 파일이 존재해야 합니다. 하지만 일반적인 클라이언트나 API를 이용해서는 우리가 아는 루트 경로 상에 BLOB 객체를 올릴 수 없습니다. 어떻게 하면 좋을까요?
여기에 대한 답이 있습니다. Windows Azure Storage는 루트 경로에 대한 예약된 컨테이너 이름을 제공합니다. 바로 $root 인데, 최상위 컨테이너 중 $root라는 이름의 컨테이너를 생성하고 여기에 파일을 업로드하면 바깥에서 보기에 루트 경로에 올라온 것과 동일하게 취급됩니다. 여기에 RIA 응용프로그램이 필요로 하는, Adobe Flash의 경우 crossdomain.xml 파일, Microsoft Silverlight의 경우 clientaccesspolicy.xml 파일을 text/xml MIME 형식으로 정확히 지정하여 업로드하면 문제가 해결됩니다.
crossdomain.xml 파일과 clientaccesspolicy.xml 파일의 예제는 휴즈플로우의 CTO이신 이길복 MVP님의 블로그 아티클 (http://gilverlight.net/2888)을 참조하시면 되겠습니다.
Project Riviera - 동적 스케일링 샘플에서 더 확장된 예제로, 윈도 애저 스토리지, Windows Workflow, 액티브 디렉터리 페더레이션 서비스, Patterns & Practices Enterprise Library 캐싱 및 로깅 응용프로그램 블럭, 윈도 라이브 ID 인증 등 엔터프라이즈 및 아키텍처에서 등장하는 기술들이 골고루 사용된 고급 샘플입니다: http://code.msdn.microsoft.com/riviera
Patterns & Practice - Windows Azure Platform을 위한 아티클이 새로 업데이트되고 있는 중입니다.
이전 시간에 이어서, 오늘은 방명록에 업로드한 이미지를 백그라운드에서 실시간으로 처리하는 Worker Role을 작성해보도록 하겠습니다. 방명록에 업로드할 수 있는 이미지의 종류가 다양하고, 간혹 디지털 카메라에서 촬영한, 웹에 업로드하기에는 적합하지 않은 고해상도의 이미지를 처리한다는 시나리오를 세워볼 수 있을 것입니다.
만들었던 Windows Azure 프로젝트를 솔루션 탐색기에서 찾아, Roles 노드를 오른쪽 버튼으로 클릭하여 새 Worker Role 추가 메뉴를 클릭한 후, 아래와 같이 Worker Role의 이름을 Guestbook_WorkerRole로 지정하고 새로 생성합니다.
Worker Role을 추가한 후에는, Storage에 만든 Table 자료를 Worker Role에서도 동일하게 액세스할 수 있도록, GuestBook_WorkerRole 프로젝트를 솔루션 탐색기에서 오른쪽 버튼으로 클릭한 후, "참조 추가" 메뉴를 클릭하여 참조 추가 대화 상자를 엽니다.
1. 참조 추가 대화 상자에서, "프로젝트" 탭을 선택하고, 기존에 만들어두었던 GuestBook_Data 프로젝트를 지정합니다.
2. 이미지를 처리해야 하므로, GDI+ API를 포함하는 System.Drawing 어셈블리가 필요합니다. 마찬가지로 참조 추가 대화 상자에서 System.Drawing 어셈블리를 추가합니다.
참조 추가를 끝낸 후에는 WorkerRole.cs 파일 상단에 네임스페이스 참조를 아래와 같이 추가합니다.
using System.IO;
using System.Drawing;
using GuestBook_Data;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
public override bool OnStart()
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
// Restart the role upon all configuration changes
RoleEnvironment.Changing += RoleEnvironmentChanging;
// read storage account configuration settings
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
});
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
// initialize blob storage
CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
container = blobStorage.GetContainerReference("guestbookpics");
// initialize queue storage
CloudQueueClient queueStorage = storageAccount.CreateCloudQueueClient();
queue = queueStorage.GetQueueReference("guestthumbs");
Trace.TraceInformation("Creating container and queue...");
bool storageInitialized = false;
while (!storageInitialized)
{
try
{
// create the blob container and allow public access
container.CreateIfNotExist();
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
// create the message queue
queue.CreateIfNotExist();
storageInitialized = true;
}
catch (StorageClientException e)
{
if (e.ErrorCode == StorageErrorCode.TransportError)
{
Trace.TraceError("Storage services initialization failure. "
+ "Check your storage account configuration settings. If running locally, "
+ "ensure that the Development Storage service is running. Message: '{0}'", e.Message);
System.Threading.Thread.Sleep(5000);
}
else
{
throw;
}
}
}
return base.OnStart();
}
위의 코드에서, BLOB 저장소와 큐 저장소에 대한 정보를 초기화 단계에서 확보하는 것을 볼 수 있습니다. Worker Role의 관점에서 보면, BLOB 저장소는 처리 대상 이미지와 처리 결과 이미지를 입력받거나 출력하는 대상이고, 큐 저장소를 통하여 작업을 지시받고 결과를 반환할 수 있습니다.
그리고 아래와 같이 Run 메서드를 작성합니다.
public override void Run()
{
Trace.TraceInformation("Listening for queue messages...");
while (true)
{
try
{
// retrieve a new message from the queue
CloudQueueMessage msg = queue.GetMessage();
if (msg != null)
{
// parse message retrieved from queue
var messageParts = msg.AsString.Split(new char[] { ',' });
var uri = messageParts[0];
var partitionKey = messageParts[1];
var rowkey = messageParts[2];
Trace.TraceInformation("Processing image in blob '{0}'.", uri);
// download original image from blob storage
CloudBlockBlob imageBlob = container.GetBlockBlobReference(uri);
MemoryStream image = new MemoryStream();
imageBlob.DownloadToStream(image);
image.Seek(0, SeekOrigin.Begin);
// create a thumbnail image and upload into a blob
string thumbnailUri = String.Concat(Path.GetFileNameWithoutExtension(uri), "_thumb.jpg");
CloudBlockBlob thumbnailBlob = container.GetBlockBlobReference(thumbnailUri);
thumbnailBlob.UploadFromStream(CreateThumbnail(image));
// update the entry in table storage to point to the thumbnail
var ds = new GuestBookEntryDataSource();
ds.UpdateImageThumbnail(partitionKey, rowkey, thumbnailBlob.Uri.AbsoluteUri);
// remove message from queue
queue.DeleteMessage(msg);
Trace.TraceInformation("Generated thumbnail in blob '{0}'.", thumbnailBlob.Uri);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
catch (StorageClientException e)
{
Trace.TraceError("Exception when processing queue item. Message: '{0}'", e.Message);
System.Threading.Thread.Sleep(5000);
}
}
}
while 구문을 통하여, 큐로부터 메시지를 수신하고, BLOB 스토리지로부터 이미지 데이터를 로드하여 처리하는 과정을 코드로 작성한 것입니다. 처리가 끝난 후에는, 큐에 쌓여있는 메시지를 제거하고 다음 메시지를 수신할 때 까지 대기하게 됩니다.
만약 윗 부분의 코드를 비동기 패턴으로 작성한다면, 좀 더 효율적으로 동작하는 Worker Role 인스턴스를 만들 수도 있을 것입니다. (Worker Role 하나가 처리할 수 있는 가용성의 범위는 VM Size에 따라 달라질 수 있지만 보통의 경우, 많은 사용자가 접속을 하게 되더라도 거의 무리 없이 소화가 가능할 것입니다.)
그리고, 위의 코드에서 실제 썸네일 생성을 담당하는 코드는 아래와 같습니다.
private Stream CreateThumbnail(Stream input)
{
var orig = new Bitmap(input);
int width;
int height;
if (orig.Width > orig.Height)
{
width = 128;
height = 128 * orig.Height / orig.Width;
}
else
{
height = 128;
width = 128 * orig.Width / orig.Height;
}
var thumb = new Bitmap(width, height);
using (Graphics graphic = Graphics.FromImage(thumb))
{
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphic.DrawImage(orig, 0, 0, width, height);
var ms = new MemoryStream();
thumb.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
}
이로서, Worker Role에 대한 구현도 끝이 났습니다. 아직 한 가지가 더 남았는데, 바로 Web Role과 Worker Role을 이어주기 위하여 Web Role에도 큐에 대한 처리가 들어가야 한다는 점입니다. 이제 다시 Web Role 프로젝트로 돌아가서 코드를 조금 수정해보도록 하겠습니다.
메인 웹 페이지 (Default.aspx)의 코드 비하인드에, 아래와 같이 정적 변수를 추가합니다.
private static CloudQueueClient queueStorage;
그리고, 파일을 업로드할 때의 버튼 클릭 이벤트에, 기존에 작성하였던 BLOB에 이미지를 저장하는 코드 아랫 부분에, 큐에 메시지를 넣는 부분을 좀 더 추가합니다. 아래와 같을 것입니다.
protected void SignButton_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
InitializeStorage();
...
// create a new entry in table storage
GuestBookEntry entry = new GuestBookEntry() { GuestName = NameTextBox.Text, Message = MessageTextBox.Text, PhotoUrl = blob.Uri.ToString(), ThumbnailUrl = blob.Uri.ToString() };
GuestBookEntryDataSource ds = new GuestBookEntryDataSource();
ds.AddGuestBookEntry(entry);
System.Diagnostics.Trace.TraceInformation("Added entry {0}-{1} in table storage for guest '{2}'", entry.PartitionKey, entry.RowKey, entry.GuestName);
// added code
// queue a message to process the image
var queue = queueStorage.GetQueueReference("guestthumbs");
var message = new CloudQueueMessage(String.Format("{0},{1},{2}", uniqueBlobName, entry.PartitionKey, entry.RowKey));
queue.AddMessage(message);
System.Diagnostics.Trace.TraceInformation("Queued message to process blob '{0}'", uniqueBlobName);
}
NameTextBox.Text = "";
MessageTextBox.Text = "";
DataList1.DataBind();
}
그리고, InitializeStorage 메서드도 조금 수정하면 끝이 납니다.
private void InitializeStorage()
{
...
try
{
...
// configure container for public access
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
// added code
// create queue to communicate with worker role
queueStorage = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueStorage.GetQueueReference("guestthumbs");
queue.CreateIfNotExist();
}
catch (WebException)
{
...
}
storageInitialized = true;
}
}
이제 완성된 Cloud Application을 직접 테스트해보겠습니다. F5 키를 눌러서 디버그를 시작합니다. 코드 상에 오류가 있을 경우 컴파일 오류나 경고가 발생할 수 있으며, 이러한 부분들을 모두 해결해야 합니다. 정상적으로 디버그 모드에 들어가게 되면, 작업 표시줄의 트레이 아이콘 영역에 아래와 같이 Development Fabric 트레이 아이콘이 나타납니다.
Web Role 프로젝트가 있으므로, Internet Explorer 또한 같이 시작될 것입니다. Web Role의 실행 결과를 보여주는 Internet Explorer 창이 아래와 같이 나타나는지 확인합니다.
방명록을 작성하고, 첨부할 사진으로 고해상도의 사진을 업로드한 후, 연필 모양의 이미지를 클릭하면 업로드가 됩니다. 테스트해볼만한 고해상도 사진을 찾으려면, Windows XP 이상의 운영 체제들은 모두 %windir%\Web\Wallpapers 폴더의 이미지를 사용하면 됩니다.
이미지를 업로드한 직후에는 이미지가 있는 그대로 표시됩니다. 하지만 타이머를 이용하여 주기적으로 Refresh 하도록 페이지를 구성하였기 때문에, 잠시 후 (약 5초 후)에는 아래와 같이 알맞게 크기 조절된 이미지가 대신 표시되는 것을 볼 수 있습니다.
세 번의 포스팅에 걸쳐서 Windows Azure로 만드는 간단한 방명록 예시를 살펴보았습니다. 2010년 2월 27일에 있을 Exploring Windows Azure 세미나 ([세미나] Exploring Windows Azure)를 통하여 실제로 프로그래밍하는 모습을 보여드릴 수 있을 것이니 많은 참석 부탁드립니다.
Windows Azure 개발 환경 및 기능 살펴보기에 대한 세미나를 준비하는 도중에 테스트를 위하여 설치와 테스트를 병행하던 도중, 문제에 빠질 수 있는 부분들이 몇 가지 있을 것으로 예상되어 개발 환경을 구축하는 방법에 대한 글을 정리하여 올려봅니다.
1. 시스템의 최소 요구 사항을 확인합니다.
Windows Azure 개발 환경을 구축하기 위해서는 시스템이 Windows Vista Service Pack 1 이상 - 또는 - Windows Server 2008을 실행 중이어야 합니다. Windows XP와 Windows Server 2003에서는 Windows Azure 개발 환경을 구축할 수 없음을 유의합니다. Windows Vista RTM 버전을 사용 중인 경우, 반드시 Service Pack 1을 설치하여야 합니다.
2. 인터넷 정보 서비스 (IIS) 및 WCF HTTP 활성화 옵션이 설정되어있는지 확인합니다.
Windows Azure 개발 환경을 구축하기 위해서는 시스템에 Internet Information Services (인터넷 정보 서비스)와 함께, WCF HTTP 기반 활성화 옵션이 설정되어있어야 합니다. 이를 확인하시려면 각 운영 체제 별로 다음과 같이 실행합니다.
Windows Vista 및 Windows 7의 경우
시작 메뉴 -> 설정 -> 제어판 -> 프로그램 -> 프로그램 및 기능 순으로 선택합니다.
Windows 기능 켜고 끄기를 선택합니다.
Microsoft .NET Framework 3.0 (Windows 7의 경우 Microsoft .NET Framework 3.5.1)아래의 Windows Communication Foundation HTTP 활성화에 체크합니다.
Internet Information Services (또는 인터넷 정보 서비스) 아래의 World Wide Web 서비스 아래의 응용프로그램 개발 기능 아래에서 ASP.NET과 CGI에 체크합니다.
선택한 항목들을 설치합니다.
Windows Server 2008 및 Windows Server 2008 SP1의 경우 (Core 버전은 해당되지 않습니다)
시작 메뉴 -> 프로그램 -> 관리 도구 -> 서버 관리자 순으로 선택합니다.
서버 관리자 화면에서, "기능 요약"의 "추가"를 선택합니다.
"추가" 대화 상자에서, Microsoft .NET Framework 3.0 (Windows Server 2008 SP1의 경우 Microsoft .NET Framework 3.5.1) 아래의 WCF 활성화 아래의 HTTP 활성화를 선택한 후, "다음" 버튼을 클릭합니다.
"역할 요약" 단계에서, 웹 서버 (IIS) 항목이 목록 중에 포함되어있는지 확인합니다. 만약 없을 경우, "역할 추가" 버튼을 클릭합니다.
"역할 추가" 대화 상자에서, "역할 요약" 아래의 "웹 서버 (IIS)"를 선택합니다.
웹 서버 관리 대화 상자에서 "서비스 역할 추가"를 클릭합니다.
나타나는 대화 상자에서 "웹 서버" 아래의 "응용프로그램 개발" 아래의 "ASP.NET"과 "CGI"를 선택하고, 다음 버튼을 클릭하여 선택한 항목들을 설치합니다.
3. Visual Studio를 설치합니다.
Visual Studio 2008 Professional 이상의 버전이 필요하며, Visual Studio 2008 Professional을 가지고 있지 않은 경우, http://www.microsoft.com/express/ 에서 Visual Web Developer 2008 SP1을 다운로드하여 설치할 수 있습니다.
Visual Studio 2010에서 테스트해보기를 원하는 경우, Visual Studio 2010 Beta 2 - 또는 - http://www.microsoft.com/express/ 에서 Visual Web Developer 2010 Beta 2를 무료로 다운로드하여 설치할 수 있습니다.
4단계의 내용과 관련하여, 설치 시 자동으로 선택되는 SQL Server 2005 - 또는 SQL Server 2008 Express Edition은 같이 설치해주실 것을 권장합니다.
4. Microsoft SQL Server 2005 - 또는 - Microsoft SQL Server 2008 인스턴스를 확인합니다.
Windows Azure의 Storage 기능을 로컬 컴퓨터에서 테스트해보기 위하여, Microsoft SQL Server 2005 버전 이상의 데이터베이스 인스턴스가 필요합니다. 개발 목적으로 사용하기 위하여, 무료로 Express Edition을 다운로드받을 수 있으며, Visual Studio 2008 설치 시 기본 옵션으로 설치하였을 경우 이미 시스템에 하나 이상의 SQL Server Express Edition이 설치되어있을 것입니다.
7. KB967631 핫픽스 설치 (운영 체제 무관, Visual Studio 2008 SP1 및 Visual Web Developer 2008 SP1 사용 시 설치 필요)
운영 체제에 관계없이, Visual Studio 2008 SP1 및 Visual Web Developer 2008 SP1을 사용하여 Windows Azure SDK 및 Windows Azure Tools 2009년 11월 버전을 활용하는 경우, http://go.microsoft.com/fwlink/?LinkId=145526 에서 KB967631 핫 픽스를 설치하여 디버깅에 관련된 문제점을 수정할 수 있습니다.
8. KB967131 핫픽스 설치 (개발 도구 무관, Windows 7, Windows Server 2008 SP2 미만인 경우 설치 필요)
개발 도구 버전에 관계 없이, Windows Vista 모든 버전, Windows Server 2008 SP1의 경우 http://support.microsoft.com/kb/967131 에서 FastCGI 기반의 개발을 정상적으로 테스트해볼 수 있도록 시스템을 수정할 수 있습니다.
9. KB963676 핫픽스 설치 (개발 도구 무관, Windows 7 이외의 모든 운영 체제에서 설치 필요)
개발 도구 버전에 관계없이, Windows Vista 및 Windows Server 2008은 KB971842 핫 픽스를, Windows 7 및 Windows Server 2008 R2는 KB977420 핫 픽스를 설치하여, Windows Azure Web Role 위에서 실행되는 WCF 서비스에 대한 참조를 클라이언트에서 정확하게 받아들일 수 있도록 할 수 있습니다.