큐(Queue) 저장소 서비스 사용하기
Windows Azure 큐(Queue)는 많은 양의 메세지를 저장해 둘 수 있는 저장소이며, 인증된 사용자가 HTTP나 HTTPS를 사용하여 전 세계 어디서나 접근할 수 있습니다. 큐(Queue) 저장소는 일반적으로 Windows Azure 웹 역할(Wen Role)에서 작업 역할(Worker Role)로 메세지를 전달하기 위해서 혹은 비동기식으로 처리되는 작업의 백로그를 생성하기 위해서 사용합니다.
이번 컬럼에서는 Windows Azure 큐(Queue) 저장소 서비스를 사용하는 일반적인 시나리오를 살펴보도록 하겠습니다. 예제는 C#과 .NET API를 사용하여 작성되었습니다. 이번 예제 시나리오는 큐(Queue) 메세지를 살펴보고, 가져오고, 추가 및 삭제할 뿐 만 아니라 큐(Queue) 자체를 생성하고 삭제하는 것도 다룰 예정입니다. 큐(Queue)에 관한 더욱 상세한 정보는 마지막에 있는 “다음으로 볼 내용”을 참고해 주십시오.
목차
- 큐(Queue) 저장소란 무엇인가?
- 개념
- Windows Azure 저장소 계정 만들기
- Visual Studio에서 Windows Azure 프로젝트 만들기
- 저장소에 접근할 수 있도록 응용 프로그램 설정하기
- Windows Azure 저장소 연결 문자열 설정하기
- How To: 큐(Queue) 만들기
- How To: 큐(Queue)에 메세지 추가하기
- How To: 다음 메세지 엿보기
- How To: 큐 메세지 내용 수정하기
- How To: 다음 메세지 가져오고 삭제하기
- How To: 메세지 가져오기의 추가적인 옵션들
- How To: 큐(Queue)되어진 메세지의 갯수 구하기
- How To: 큐(Queue) 삭제하기
- 다음으로 볼 내용들
큐(Queue) 저장소란 무엇인가?
Windows Azure 큐(Queue)는 인증된 사용자가 HTTP나 HTTPS를 사용하여 전 세계 어디서나 접근할 수 있는 수 많은 메시지들을 저장하기 위한 서비스입니다. 단일 큐(Queue) 메세지는 64KB까지 사용 가능하며, 하나의 큐(Queue)는 단일 저장소 계정의 총 용량인 100 TB 범위 내에서 수 백만 개의 메세지를 가질 수 있습니다. 큐 저장소는 일반적으로 다음과 같은 경우에 사용됩니다.
- 비동기식으로 처리되는 작업의 백로그 생성을 위해서
- Windows Azure 웹 역할(Wen Role)에서 작업 역할(Worker Role)로 메세지들을 전달하기 위해서
개념들
큐(Queue) 서비스는 아래와 같은 구성요소를 포함하고 있습니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/queue1.png
URL 형식 : 큐(Queue)들은 아래와 같은 URL 형식의 주소를 가집니다.
http://<저장소 계정>.queue.core.windows.net/<큐 이름>
아래의 URL 주소는 위 그림의 큐들 중 하나를 나타낸 것 입니다.
http://myaccount.queue.core.windows.net/imagesToDownload
-
저장소 계정 : 모든 종류의 Windows Azure 저장소는 저장소 계정을 통해서 접근이 가능합니다. 저장소 계정은 큐(Queue)를 접근하기 위한 최상위 수준의 네임스페이스(namespace)이기도 합니다. 단일 저장소 계정 안에 있는 블랍(BLOB), 테이블, 큐(Queue)의 총 크기는 모두 합해서 100 TB를 초과할 수 없습니다
- 큐(Queue) : 단일 큐(Queue)는 수 많은 메세지들의 집합으로 이루어집니다. 그리고, 모든 메세지는 단일 큐(Queue)에 포함됩니다.
- 메세지 : 어떤 형식의 메세지이든 단일 메시지는 64 KB까지 사용가능합니다.
Windows Azure 저장소 계정 만들기
저장소 서비스를 사용하기 위해서는 Windows Azure 저장소 계정이 필요합니다. 아래와 같은 순서대로 따라 하시면 수동으로 저장소 계정을 생성할 수 있습니다. (REST API를 이용하여 프로그램을 만들어서 저장소 계정을 생성할 수도 있습니다):
- Windows Azure 관리 포탈에 로그인합니다.
하단 메뉴 바의 좌측에 있는 +NEW 버튼을 클릭합니다.

출처 : http://www.windowsazure.com/media/devcenter/shared/plus-new.png
Storage를 선택한 다음 Quick Create를 클릭합니다.

출처 : http://www.windowsazure.com/media/devcenter/shared/quick-storage.png
- URL 란에는 저장소 계정 URI의 하위 도메인으로 사용할 이름을 입력합니다. 3글자 이상 24글자 이하의 소문자나 숫자로 입력이 가능합니다. 해당 이름은 블랍(BLOB), 큐(Queue) 그리고 테이블 데이터에 접근하기 위해 사용되는 URI의 호스트 명으로 사용됩니다.
- REGION/AFFINITY GROUP에서 저장소의 물리적인 위치를 설정합니다. 일반적으로 Windows Azure로 프로그램을 작성한다면 해당 애플리케이션이 위치해야 할 지역에 가까운 곳을 선택하면 됩니다.
- CREATE STORAGE ACCOUNT를 클릭합니다.
Visual Studio에서 Windows Azure프로젝트 만들기
이번에는 비주얼 스튜디오를 사용하여 windows azure cloud 프로젝트에서 저장소 기능을 사용하는 방법에 대해 알아보도록 하겠습니다. 먼저 windows azure cloud 프로젝트를 어떻게 만드는지부터 살펴보도록 해요.
- .NET 용 Windows Azure SDK가 설치되어 있지 않다면 다운받아서 설치합니다.
- MSDN에서 "Visual Studio에서 Windows Azure 프로젝트 생성하기"를 읽고, 해당 절차에 따라서 하나 이상의 웹 롤(Web Role)이나 작업 롤(Worker Role)을 가진 Windows Azure 프로젝트를 생성합니다.
응용 프로그램에서 저장소 접근 설정하기
만들어진 프로젝트(project)의 웹 롤(web role)이나 작업 롤(worker role)은 테이블 서비스(table service)를 사용하기 위해서 필요한 대부분의 참조들을 이미 포함하고 있을 것입니다. 하지만, System.DataSerivces.Client는 수동으로 직접 추가할 필요가 있습니다.
- 솔루션 탐색기의 [참조]에서 마우스 오른쪽 클릭을 한다면 나오는 팝업메뉴에서 [참조 추가]를 선택합니다.
- .NET 탭에서 System.Data.Services.Client를 선택합니다.
- OK 버튼을 클릭합니다.
그 다음, Windows Azure 테이블 서비스를 사용할 C# 파일의 상단에 아래와 같은 코드를 추가합니다.
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Data.Services.Client;
Windows Azure 저장소 연결 문자열 설정하기
Windows Azure 닷넷 저장소 API는 저장소 연결 문자열을 통해서 저장소 서비스에 접근할 수 있는 끝점과 권한을 설정할 수 있도록 되어 있습니다. 그리고, 해당 연결 문자열은 프로그램 내에 하드코딩 하기 보다는 설정 파일에 넣는 것이 좋습니다.
- Windows Cloud Azure 서비스를 사용한다면 Windows Azure 서비스 설정 파일(*.csdef와 *.cscfg)에 연결문자열을 저장하는 것이 좋습니다.
- Windows Azure 웹 사이트나 가상머신(VM)을 이용한다면 닷넷 설정 파일(web.config 등)에 저장하는 것이 좋습니다.
2가지 경우 모두 CloudConfigurationManager 클래스의 정적 메서드인 GetSetting을 이용하여 연결 문자열을 가져올 수 있습니다.
클라우드 서비스에서 연결 문자열 설정하기
Windows Azure Cloud 서비스 프로젝트에서 서비스 설정 방식은 고유한 단일 메커니즘을 사용하기에, 설정을 변경해야 하는 경우 응용 프로그램을 재 배포하지 않고도 Windows Azure 관리 포털의 설정을 변경하는 것 만으로도 동적인 변경이 가능합니다.
이제, Windows Azure 서비스 설정에 연결 문자열을 설정해 보도록 하겠습니다.
비주얼 스튜디오의 솔루션 탐색기를 엽니다. Windows Azure 배포 프로젝트의 Roles라는 폴더를 마우스 오른쪽 클릭하거나, 웹 롤(Web Role) 또는 작업 롤(Worker Role)을 마우스 오른쪽 클릭하여 [속성]을 선택합니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob5.png
Settings라는 탭을 클릭하고 Add Setting이라는 버튼을 누릅니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob6.png
그러면 새로운 "Setting1"이라는 줄이 설정에 나타납니다.
새로 만들어진 "Setting1"이라는 줄에서 Type이라는 열의 선택박스를 Connection String으로 선택합니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob7.png
-
해당 줄 우측 끝에 있는 [...]이라는 버튼을 클릭합니다. 그러면 Storage Account Connection String(저장소 계정 연결 문자열)이라는 대화상자가 열립니다.
해당 창에서 로컬 컴퓨터에서 동작하는 Windows Azure 저장소 에뮬레이트(Emulator)를 선택하거나 클라우드의 실제 저장소 계정을 선택할 수 있습니다. 만일, 실제 클라우드 저장소를 사용하려 한다면 Enter storage account credentials를 선택하고 앞서 설정하였던 저장소 계정이름을 Account name에 넣은 다음 저장해 둔 Primary Access Key값을 Account key입력상자에 입력하면 됩니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob8.png
해당 줄에 Name이라는 컬럼이 "Setting1"이라고 되어 있는데 이걸 보다 직관적인 StorageConnectionString과 같은 형태로 변경합니다. 이 명칭은 나중에 나오는 예제 소스에서 사용될 것 입니다.

출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob9.png
웹사이트나 가상 머신에서 연결문자열 설정하기
웹 사이트나 가상 머신을 사용한다면 닷넷 설정 파일(web.config 등)을 이용하실 것을 추천합니다. <appSettings>에 연결 문자열을 아래와 같은 형식으로 저장할 수 있습니다.
<configuration>
<appSettings>
<add key="StorageConnectionString"
value="DefaultEndpointsProtocol=https;AccountName=[AccountName];AccountKey=[AccountKey]" />
</appSettings>
</configuration>
좀 더 자세한 정보는 연결문자열 설정하기를 참조해 주십시오.
자, 이제 How to 가이드를 공부하기 위한 준비가 완료되었습니다~~!
How To : 큐(Queue) 만들기
큐(Queue)에 대한 참조 개체는 CloudQueueClinet 개체를 통해서 생성할 수 있습니다. 아래의 코드는 CloudQueueClient 개체를 생성하는 코드의 예입니다. 이번 강좌의 모든 코드는 저장소 연결 문자열을 Windows Azure 응용 프로그램의 서비스 설정에 저장해두고 사용하는 것으로 가정하고 있습니다. 물론, CloudStorageAccount 개체를 이와는 다른 방식으로도 생성할 수 있습니다. 이에 관한 상세한 내용은 CloudStorageAccount 문서를 참고하시기 바랍니다.
// 연결문자열을 통해서 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
//큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
queueClient 객체를 이용하면, 사용하려는 큐(Queue)의 참조는 가져올 수 있을 뿐만 아니라 해당 큐(Queue)가 존재하지 않을 경우에는 새로 생성할 수도 있습니다.
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 해당 큐가 이미 존재하지 않는다면 해당 큐(Queue)를 생성합니다.
queue.CreateIfNotExist();
How To : 큐(Queue)에 메세지 추가하기
기존에 존재하는 큐(Queue)에 메세지를 추가하기 위해서는, 먼저 새로운 CloudQueueMessage를 생성한 뒤, AddMessage 메서드를 호출하면 됩니다. CloudQueueMessage는 UTF-8 형식의 문자열이나 byte 배열을 사용하여 생성될 수 있습니다. 다음은 큐가 존재하지 않는다면 생성한 다음, "Hello, World"라는 메세지를 추가하는 코드를 보여주고 있습니다.
// 접속 문자열을 통해서 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
//큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 만약에 존재하지 않는다면 생성합니다.
queue.CreateIfNotExist();
// 메세지를 생성하고, 이를 큐(Queue)에 추가합니다.
CloudQueueMessage message = new CloudQueueMessage("Hello, World");
queue.AddMessage(message);
How To : 다음 메세지 엿보기
PeekMessage 메서드를 이용하면 큐(Queue)에서 메세지를 삭제하지 않고도 큐 앞 단에 있는 메시지를 살펴볼 수 있습니다.
// 연결 문자열로부터 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 다음 메세지를 살펴봅니다.
CloudQueueMessage peekedMessage = queue.PeekMessage();
How To : 큐에 저장된 메세지 내용 변경하기
큐(Queue)에 있는 메세지의 내용을 변경할 수도 있습니다. 만일, 작업(task)를 나타내는 메세지가 있다고 가정하면, 이러한 수정 기능을 이용하여 그 작업의 진행 상태를 수정할 수도 있을 것입니다. 다음의 코드는 큐(Queue) 메시지를 새로운 내용으로 변경하고 있으며, invisibility 타임아웃을 60초 더 연장하도록 지정하고 있습니다(역자 주 : invisibility 타임아웃이 지정되면 다른 코드에서는 해당 큐를 지정된 시간 동안 볼 수 없습니다). 이는 해당 메세지와 관련된 작업의 상태를 저장한 다음, 그 메시지를 클라이언트가 계속해서 다룰 수 있도록 1분의 시간을 더 주는 것입니다. 이 방식을 이용하면 진행 중인 작업이 하드웨어적, 소프트웨어적인 문제로 인하여 진행이 실패하였다고 하더라도 처음부터 다시 진행할 필요 없이, 큐(Queue) 메시지에 대한 여러 단계의 워크 플로우를 추적할 수 있습니다. 일반적으로는 재시도 횟수도 지정하여, 해당 메세지의 재 시도 횟수가 n번 이상이 되면 해당 메세지를 삭제하곤 합니다. 이는 매번 실행될 때마다 계속해서 에러가 발생하는 것을 방지하기 위함입니다.
// 연결 문자열로 부터 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue)참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
CloudQueueMessage message = queue.GetMessage();
message.SetMessageContent("Updated contents.") ;
queue.UpdateMessage(message,
TimeSpan.FromSeconds(0.0), // 즉시 보여줍니다.
MessageUpdateFields.Content | MessageUpdateFields.Visibility);
How To : 다음 메세지 가져오고 삭제하기
2단계의 과정을 통해서 큐(Queue)로부터 메세지를 가져와 삭제할 수 있습니다. 먼저 GetMessage를 호출하여 다음 메세지를 가지고 옵니다. 이렇게 하면, 다른 코드에서 해당 큐(Queue)로부터 메세지를 읽으려고 해도 해당 메세지는 볼 수 없게 됩니다. 기본적으로 이 메세지는 30초간 보이지 않는 상태가 됩니다. 해당 메세지를 큐(Queue)로부터 삭제하려면 DeleteMessage를 호출해야 합니다. 이러한 2 단계의 메세지 삭제과정은 여러분의 코드가 하드웨어나 소프트웨어적인 문제로 인해 메시지를 처리하는 데 실패하는 경우, 또 다른 코드 인스턴스에서 같은 메세지를 가져가서 처리할 수 있도록 해줍니다. 해당 메세지의 작업이 종료된 후에는 즉시 DeleteMessage를 호출해야 합니다.
// 연결문자열로 부터 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 다음 메세지를 가져옵니다.
CloudQueueMessage retrievedMessage = queue.GetMessage();
// 30초 이내에 해당 메세지를 처리하고 해당 메세지를 삭제합니다.
queue.DeleteMessage(retrievedMessage);
메세지 가져오고 삭제하기의 추가적인 옵션들
큐(Queue)로부터 메세지를 가져오는 방법을 2가지 정도의 방식으로 바꾸어 볼 수도 있는데요. 첫 번째는 한 번에 다수의 메세지(32개 까지 가능)를 가져오도록 하는 것이고, 두 번째는 여러분의 코드가 메세지를 완전히 처리하는데 더 적은 시간 혹은 더 많은 시간이 걸리도록 invisibility 타임아웃을 짧거나 길게 설정하는 것입니다. 다음 코드는 GetMessages 메서드를 사용하여 한번의 호출로 20개의 메시지를 가져온 다음, foreach 루프를 사용하여 각각의 메시지를 처리하는 예를 보여주고 있습니다. 또한, 각각의 메시지에 대해 invisibility 타임아웃을 5분씩 설정하고 있기도 합니다. 5분의 타임아웃은 모든 메시지에 대해 동시에 시작되며, GetMessages를 호출한 지 5분이 지나고 나면, 아직 삭제되지 않은 모든 메시지들은 다시 보여지게 된다는 점을 기억하시기 바랍니다.
// 연결 문자열을 통하여 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
foreach (CloudQueueMessage message in queue.GetMessages(20, TimeSpan.FromMinutes(5)))
{
// 5분 이내에 모든 메시지에 대한 처리를 수행합니다. 각각의 메세지를 처리한 후에는 삭제합니다.
queue.DeleteMessage(message);
}
How To : 큐(Queue)되어진 메세지의 개수 구하기
큐(Queue) 안에 있는 메시지들의 대략적인 갯수를 구할 수도 있습니다. RetrieveApproximateMessageCount 메서드는 큐(Queue) 서비스에게 해당 큐 안에 얼마나 많은 메시지가 있는 지를 세어보도록 요청합니다. 단, 이 개수는 단지 대략적인 개수라는 점에 주의하셔야 합니다. 왜냐하면, 우리의 요청에 따라 큐(Queue) 서비스가 개수를 세어보고 응답하는 사이에 메시지가 추가되거나 삭제될 수 있기 때문입니다. 반면, ApproximateMethodCount라는 속성은 큐(Queue) 서비스를 전혀 호출하지 않고 RetrieveApproximateMessageCont 호출에 의해 가져왔던 마지막(최신) 값을 가지고 있다가 그를 반환합니다.
// 연결 문자열을 통하여 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 큐(Queue) 참조에서 대략적인 메세지 갯수를 반환받습니다.
int freshMessageCount = queue.RetrieveApproximateMessageCount();
// 위의 방법으로 반환받아 저장해놓은 값을 반환받습니다.
int? cachedMessageCount = queue.ApproximateMessageCount;
How To: 큐(Queue) 삭제
큐(Queue)와 그 안에 포함된 모든 메세제를 삭제하기 위해서는 큐(Queue) 개체의 Delete 메서드를 호출하면 됩니다.
// 연결 문자열을 통하여 저장소 계정을 반환받습니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// 큐(Queue) 클라이언트를 생성합니다.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// 큐(Queue) 참조를 반환받습니다.
CloudQueue queue = queueClient.GetQueueReference("myqueue");
// 큐(Queue) 를 삭제합니다.
queue.Delete();
다음으로 볼 내용들
이제 큐(Queue) 저장소의 기본 내용들을 살펴보았습니다. 좀더 복잡한 저장소 작업을 다루고 싶다면 아래의 링크를 참고하세요.