Java から Queue Storage を使用する方法
概要
このガイドでは、Azure Queue Storage サービスを使用して一般的なシナリオのためのコードを作成する方法について説明します。 サンプルは Java で記述され、 Azure Storage SDK for Javaを利用しています。 シナリオには、キュー メッセージの挿入、ピーク、取得、削除が含まれます。 キューを作成および削除するためのコードについても説明します。 キューの詳細については、「次のステップ」のセクションを参照してください。
Queue storage とは
Azure キュー ストレージは、HTTP または HTTPS を使用した認証された呼び出しを介して世界中のどこからでもアクセスできる大量のメッセージを格納するためのサービスです。 キューの 1 つのメッセージの最大サイズは 64 KB で、1 つのキューには、ストレージ アカウントの合計容量の上限に達するまで、数百万のメッセージを格納できます。 Queue storage は、多くの場合、非同期的な処理用に作業のバックログを作成するために使用されます。
Queue サービスの概念
Azure Queue サービスには、次のコンポーネントが含まれます。
ストレージ アカウント: Azure のストレージにアクセスする場合には必ず、ストレージ アカウントを使用します。 ストレージ アカウントの詳細については、「ストレージ アカウントの概要」を参照してください。
キュー: キューは、メッセージのセットを格納します。 すべてのメッセージはキューに 格納されている必要があります。 キュー名は小文字で入力する必要があります。 キューの名前付け規則については、「 Naming Queues and Metadata (キューとメタデータの名前付け規則)」を参照してください。
メッセージ: 形式を問わず、メッセージのサイズは最大で 64 KB です。 メッセージをキューで保持できる最長時間は 7 日間です。 バージョン 2017-07-29 以降では、最大有効期間を任意の正の数にすることができます。また、-1 は、メッセージが期限切れにならないことを示します。 このパラメーターを省略すると、既定の有効期間は 7 日になります。
URL 形式: キューは次の URL 形式を使って処理できます: http://
<storage account>
.queue.core.windows.net/<queue>
次の URL を使用すると、図のいずれかのキューをアドレス指定できます。
http://myaccount.queue.core.windows.net/incoming-orders
Azure のストレージ アカウントの作成
最初の Azure ストレージ アカウントを作成する最も簡単な方法は、Azure Portal を利用することです。 詳細については、「 ストレージ アカウントの作成」を参照してください。
Azure Storage アカウントは、Azure PowerShell、Azure CLI、または .NET 用 Azure ストレージ リソース プロバイダーを使用して作成することもできます。
現時点で Azure にストレージ アカウントを作成しない場合は、Azure ストレージ エミュレーターを使って、ローカル環境でコードの実行とテストを行うこともできます。 詳細については、ローカルでの Azure Storage の開発に Azurite エミュレーターを使用する方法に関するページを参照してください。
Java アプリケーションの作成
最初に、Java 用の Azure Queue Storage クライアント ライブラリ v12 に関する記事に記載されている前提条件が、開発システムによって満たされていることを確認します。
queues-how-to-v12
という名称の Java アプリケーションを作成するには:
コンソール ウィンドウ (cmd、PowerShell、Bash など) で、Maven コマンドを使用し、
queues-how-to-v12
という名前で新しいコンソール アプリを作成します。 次のmvn
コマンドを入力して "hello world" Java プロジェクトを作成します。mvn archetype:generate \ --define interactiveMode=n \ --define groupId=com.queues.howto \ --define artifactId=queues-howto-v12 \ --define archetypeArtifactId=maven-archetype-quickstart \ --define archetypeVersion=1.4
mvn archetype:generate ` --define interactiveMode=n ` --define groupId=com.queues.howto ` --define artifactId=queues-howto-v12 ` --define archetypeArtifactId=maven-archetype-quickstart ` --define archetypeVersion=1.4
プロジェクトの生成からの出力は、次のようになります。
[INFO] Scanning for projects... [INFO] [INFO] ------------------< org.apache.maven:standalone-pom >------------------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] >>> maven-archetype-plugin:3.1.2:generate (default-cli) > generate-sources @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:3.1.2:generate (default-cli) < generate-sources @ standalone-pom <<< [INFO] [INFO] [INFO] --- maven-archetype-plugin:3.1.2:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Batch mode [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.queues.howto [INFO] Parameter: artifactId, Value: queues-howto-v12 [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: package, Value: com.queues.howto [INFO] Parameter: packageInPathFormat, Value: com/queues/howto [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: package, Value: com.queues.howto [INFO] Parameter: groupId, Value: com.queues.howto [INFO] Parameter: artifactId, Value: queues-howto-v12 [INFO] Project created from Archetype in dir: C:\queues\queues-howto-v12 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.775 s [INFO] Finished at: 2020-08-17T15:27:31-07:00 [INFO] ------------------------------------------------------------------------
新しく作成した
queues-howto-v12
ディレクトリに切り替えます。cd queues-howto-v12
パッケージをインストールする
テキスト エディターで pom.xml
ファイルを開きます。 依存関係のグループに、次の dependency 要素を追加します。
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-queue</artifactId>
<version>12.6.0</version>
</dependency>
Queue ストレージにアクセスするようにアプリケーションを構成する
Azure Storage API を使用してキューにアクセスする Java ファイルの先頭には、次の import ステートメントを追加します。
// Include the following imports to use queue APIs
import com.azure.core.util.*;
import com.azure.storage.queue.*;
import com.azure.storage.queue.models.*;
Azure Storage 接続文字列の設定
Azure Storage クライアントでは、データ管理サービスにアクセスするためにストレージ接続文字列が使用されます。 ストレージ アカウントの名前とプライマリ アクセス キーを、Azure portal で確認します。 これらを接続文字列の AccountName
および AccountKey
の値として使用します。 この例では、接続文字列を保持する静的フィールドを宣言する方法を示しています。
// Define the connection-string with your values
final String connectStr =
"DefaultEndpointsProtocol=https;" +
"AccountName=your_storage_account;" +
"AccountKey=your_storage_account_key";
次のサンプルでは、ストレージ接続文字列が格納されている String
オブジェクトがあるものとします。
方法:キューを作成する
QueueClient
オブジェクトには、キューとやりとりするための操作が含まれています。 次のコードでは、QueueClient
オブジェクトを作成します。 使用するキューを作成するには、QueueClient
オブジェクトを使用します。
public static String createQueue(String connectStr)
{
try
{
// Create a unique name for the queue
String queueName = "queue-" + java.util.UUID.randomUUID();
System.out.println("Creating queue: " + queueName);
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queue = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// Create the queue
queue.create();
return queue.getQueueName();
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println("Error code: " + e.getErrorCode() + "Message: " + e.getMessage());
return null;
}
}
方法:メッセージをキューに追加する
既存のキューにメッセージを挿入するには、sendMessage
メソッドを呼び出します。 メッセージには、文字列 (UTF-8 形式) またはバイト配列のいずれかを指定できます。 キューに文字列メッセージを送信するコードを次に示します。
public static void addQueueMessage
(String connectStr, String queueName, String messageText)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
System.out.println("Adding message to the queue: " + messageText);
// Add a message to the queue
queueClient.sendMessage(messageText);
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:次のメッセージをピークする
peekMessage
を呼び出すと、キューの先頭にあるメッセージをキューから削除せずにクイック表示することができます。
public static void peekQueueMessage
(String connectStr, String queueName)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// Peek at the first message
PeekedMessageItem peekedMessageItem = queueClient.peekMessage();
System.out.println("Peeked message: " + peekedMessageItem.getMessageText());
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:キューに配置されたメッセージの内容を変更する
キュー内のメッセージの内容をインプレースで変更できます。 メッセージで作業タスクが表されている場合は、この機能を使用して、その状態を更新できます。 次のコードでは、キュー メッセージを新しい内容に更新し、表示タイムアウトを設定して 30 秒延長します。 表示タイムアウトを延長すると、クライアントでメッセージの処理をさらに 30 秒続けることができます。 再試行回数も維持できます。 メッセージの再試行回数が n 回を超えた場合は、それを削除します。 このシナリオでは、処理されるたびにアプリケーション エラーが発生するメッセージから保護されます。
次のコード サンプルでは、メッセージのキューを検索し、内容が検索文字列と一致する最初のメッセージを見つけて、メッセージの内容を変更し、終了します。
public static void updateQueueMessage
(String connectStr, String queueName,
String searchString, String updatedContents)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// The maximum number of messages to retrieve is 32
final int MAX_MESSAGES = 32;
// Iterate through the queue messages
for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES))
{
// Check for a specific string
if (message.getMessageText().equals(searchString))
{
// Update the message to be visible in 30 seconds
queueClient.updateMessage(message.getMessageId(),
message.getPopReceipt(),
updatedContents,
Duration.ofSeconds(30));
System.out.println(
String.format("Found message: \'%s\' and updated it to \'%s\'",
searchString,
updatedContents)
);
break;
}
}
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
次のコード サンプルでは、キューで最初に参照したメッセージのみが更新されます。
public static void updateFirstQueueMessage
(String connectStr, String queueName, String updatedContents)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// Get the first queue message
QueueMessageItem message = queueClient.receiveMessage();
// Check for a specific string
if (null != message)
{
// Update the message to be visible in 30 seconds
UpdateMessageResult result = queueClient.updateMessage(message.getMessageId(),
message.getPopReceipt(),
updatedContents,
Duration.ofSeconds(30));
System.out.println("Updated the first message with the receipt: " +
result.getPopReceipt());
}
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:キューの長さを取得する
キュー内のメッセージの概数を取得できます。
getProperties
メソッドから、キューに現在置かれているメッセージの数など、いくつかの値が返されます。 要求の後でメッセージが追加または削除される可能性があるため、これらの値はあくまでも概数です。
getApproximateMessageCount
メソッドからは、Queue Storage を呼び出さず、getProperties
を呼び出すことで取得された最後の値が返されます。
public static void getQueueLength(String connectStr, String queueName)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
QueueProperties properties = queueClient.getProperties();
long messageCount = properties.getApproximateMessagesCount();
System.out.println(String.format("Queue length: %d", messageCount));
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:次のメッセージをデキューする
コードでは、2 つの手順でキューからメッセージをデキューします。
receiveMessage
を呼び出すと、キュー内の次のメッセージを取得します。
receiveMessage
から返されたメッセージは、このキューからメッセージを読み取る他のコードから参照できなくなります。 既定では、このメッセージを参照できない状態は 30 秒間続きます。 また、キューからのメッセージの削除を完了するには、deleteMessage
を呼び出す必要があります。 コードでのメッセージの処理が失敗した場合でも、この 2 段階のプロセスにより、同じメッセージを取得して再試行できます。 ご自分のコードで、メッセージが処理された直後に deleteMessage
を呼び出します。
public static void dequeueMessage(String connectStr, String queueName)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// Get the first queue message
QueueMessageItem message = queueClient.receiveMessage();
// Check for a specific string
if (null != message)
{
System.out.println("Dequeing message: " + message.getMessageText());
// Delete the message
queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
}
else
{
System.out.println("No visible messages in queue");
}
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
メッセージのデキュー用の追加オプション
キューからのメッセージの取得をカスタマイズする方法は 2 つあります。 1 つ目の方法では、メッセージのバッチ (最大 32 個) を取得します。 2 つ目の方法では、コードで各メッセージを完全に処理できるように、非表示タイムアウトの設定を長くまたは短くします。
次のコード例では、receiveMessages
メソッドを使用して、1 回の呼び出しで 20 個のメッセージを取得します。 その後、for
ループを使用して、各メッセージを処理します。 また、各メッセージの非表示タイムアウトを 5 分 (300 秒) に設定します。 タイムアウトは、すべてのメッセージに対して同時に開始されます。
receiveMessages
を呼び出してから 5 分経過すると、削除されていないメッセージは再び見えるようになります。
public static void dequeueMessages(String connectStr, String queueName)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
// The maximum number of messages to retrieve is 20
final int MAX_MESSAGES = 20;
// Retrieve 20 messages from the queue with a
// visibility timeout of 300 seconds (5 minutes)
for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES,
Duration.ofSeconds(300), Duration.ofSeconds(1), new Context("key1", "value1")))
{
// Do processing for all messages in less than 5 minutes,
// deleting each message after processing.
System.out.println("Dequeing message: " + message.getMessageText());
queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
}
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:キューを一覧表示する
現在のキューの一覧を取得するには、QueueServiceClient.listQueues()
メソッドを呼び出します。このメソッドは、QueueItem
オブジェクトのコレクションを返します。
public static void listQueues(String connectStr)
{
try
{
// Instantiate a QueueServiceClient which will be
// used to list the queues
QueueServiceClient queueServiceClient = new QueueServiceClientBuilder()
.connectionString(connectStr)
.buildClient();
// Loop through the collection of queues.
for (QueueItem queue : queueServiceClient.listQueues())
{
// Output each queue name.
System.out.println(queue.getName());
}
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
方法:キューを削除する
キューおよびそれに格納されているすべてのメッセージを削除するには、QueueClient
オブジェクトの delete
メソッドを呼び出します。
public static void deleteMessageQueue(String connectStr, String queueName)
{
try
{
// Instantiate a QueueClient which will be
// used to create and manipulate the queue
QueueClient queueClient = new QueueClientBuilder()
.connectionString(connectStr)
.queueName(queueName)
.buildClient();
System.out.println("Deleting queue: " + queueClient.getQueueName());
// Delete the queue
queueClient.delete();
}
catch (QueueStorageException e)
{
// Output the exception message and stack trace
System.out.println(e.getMessage());
e.printStackTrace();
}
}
ヒント
Azure Storage コード サンプル レポジトリを参照してください
ダウンロードして実行できる、使いやすいエンド ツー エンドの Azure Storage コード サンプルについては、Azure Storage のサンプルの一覧を確認してください。
次のステップ
これで、Queue Storage の基本を学習できました。さらに複雑なストレージ タスクを実行するには、次のリンク先を参照してください。
- Azure Storage SDK for Java
- Azure Storage クライアント SDK リファレンス
- Azure Storage サービス REST API
- Azure Storage チーム ブログ
非推奨の Java バージョン 8 SDK を使用する関連コード サンプルについては、「Java バージョン 8 を使用したコード サンプル」を参照してください。