azure-eventhub-java について
azure-eventhub-javaは、Azure Event Hubsを通じたリアルタイムストリームアプリケーション構築用のJava SDKです。同期・非同期クライアント、バッチ送信、パーティション操作、チェックポイント対応のイベント処理を提供します。
主な機能
- 01同期・非同期のプロデューサーとコンシューマー
- 02イベントのバッチ送信
- 03パーティションまたはキーによるイベント振り分け
- 04指定位置からのイベント受信
- 05チェックポイントを使ったイベント処理
活用シーン
- 01Event Hubsへのアプリケーションイベント送信
- 02特定パーティションからのイベント消費
- 03チェックポイント付きバッチ処理
- 04リアルタイムデータ取り込みアプリの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-eventhub-javaインストール後、Claude Code で/azure-eventhub-javaを入力して読み込まれたか確認します。
詳細
Azure Event Hubs SDK for Java
Azure Event Hubs SDK for Java を使用して、リアルタイムのストリーミングアプリケーションを構築します。
インストール
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-eventhubs</artifactId>
<version>5.19.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
<version>1.20.0</version>
</dependency>
クライアントの作成
EventHubProducerClient
import com.azure.messaging.eventhubs.EventHubProducerClient;
import com.azure.messaging.eventhubs.EventHubClientBuilder;
// With connection string
EventHubProducerClient producer = new EventHubClientBuilder()
.connectionString("<connection-string>", "<event-hub-name>")
.buildProducerClient();
// Full connection string with EntityPath
EventHubProducerClient producer = new EventHubClientBuilder()
.connectionString("<connection-string-with-entity-path>")
.buildProducerClient();
DefaultAzureCredential を使用する場合
import com.azure.identity.DefaultAzureCredentialBuilder;
EventHubProducerClient producer = new EventHubClientBuilder()
.fullyQualifiedNamespace("<namespace>.servicebus.windows.net")
.eventHubName("<event-hub-name>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildProducerClient();
EventHubConsumerClient
import com.azure.messaging.eventhubs.EventHubConsumerClient;
EventHubConsumerClient consumer = new EventHubClientBuilder()
.connectionString("<connection-string>", "<event-hub-name>")
.consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
.buildConsumerClient();
非同期クライアント
import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
EventHubProducerAsyncClient asyncProducer = new EventHubClientBuilder()
.connectionString("<connection-string>", "<event-hub-name>")
.buildAsyncProducerClient();
EventHubConsumerAsyncClient asyncConsumer = new EventHubClientBuilder()
.connectionString("<connection-string>", "<event-hub-name>")
.consumerGroup("$Default")
.buildAsyncConsumerClient();
互換性のある SDK(identity/storage を含む)を固定し、java.util/time のインポートを追加してください。クライアントの宣言はそれぞれ別の選択肢です。プロデューサー、コンシューマー、チェックポイントの役割を分け、本文や接続文字列は伏せてください。永続的な処理の後にのみチェックポイントを設定し、失敗にも対処してください。チェックポイントを設定しても、Exactly-once 処理が保証されるわけではありません。キャンセルできるようサブスクリプションハンドルを保持し、すべての終了経路でクライアントを閉じるか、プロセッサーを停止してください。ErrorContext にパーティションコンテキストが含まれない場合があるため、パーティション ID を読み取る前に確認してください。バッチの再試行ではパーティションオプションを維持してください。また、送信結果が不確かな場合はイベントが重複する可能性があるため、イベント ID や照合を使用してください。
基本的なパターン
単一イベントの送信
import com.azure.messaging.eventhubs.EventData;
EventData eventData = new EventData("Hello, Event Hubs!");
producer.send(Collections.singletonList(eventData));
イベントバッチの送信
import com.azure.messaging.eventhubs.EventDataBatch;
import com.azure.messaging.eventhubs.models.CreateBatchOptions;
// Create batch
EventDataBatch batch = producer.createBatch();
// Add events (returns false if batch is full)
for (int i = 0; i < 100; i++) {
EventData event = new EventData("Event " + i);
if (!batch.tryAdd(event)) {
// Batch is full, send and create new batch
producer.send(batch);
batch = producer.createBatch();
if (!batch.tryAdd(event)) throw new IllegalArgumentException("Event exceeds empty batch capacity");
}
}
// Send remaining events
if (batch.getCount() > 0) {
producer.send(batch);
}
特定のパーティションへの送信
CreateBatchOptions options = new CreateBatchOptions()
.setPartitionId("0");
EventDataBatch batch = producer.createBatch(options);
if (!batch.tryAdd(new EventData("Partition 0 event"))) throw new IllegalArgumentException("Event too large");
producer.send(batch);
パーティションキーを指定した送信
CreateBatchOptions options = new CreateBatchOptions()
.setPartitionKey("customer-123");
EventDataBatch batch = producer.createBatch(options);
if (!batch.tryAdd(new EventData("Customer event"))) throw new IllegalArgumentException("Event too large");
producer.send(batch);
プロパティ付きイベント
EventData event = new EventData("Order created");
event.getProperties().put("orderId", "ORD-123");
event.getProperties().put("customerId", "CUST-456");
event.getProperties().put("priority", 1);
producer.send(Collections.singletonList(event));
イベントの受信(シンプルな方法)
import com.azure.messaging.eventhubs.models.EventPosition;
import com.azure.messaging.eventhubs.models.PartitionEvent;
// Receive from specific partition
Iterable<PartitionEvent> events = consumer.receiveFromPartition(
"0", // partitionId
10, // maxEvents
EventPosition.earliest(), // startingPosition
Duration.ofSeconds(30) // timeout
);
for (PartitionEvent partitionEvent : events) {
EventData event = partitionEvent.getData();
System.out.println("Body: " + event.getBodyAsString());
System.out.println("Sequence: " + event.getSequenceNumber());
System.out.println("Offset: " + event.getOffset());
}
EventProcessorClient(本番環境向け)
import com.azure.messaging.eventhubs.EventProcessorClient;
import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
import com.azure.storage.blob.BlobContainerAsyncClient;
import com.azure.storage.blob.BlobContainerClientBuilder;
// Create checkpoint store
BlobContainerAsyncClient blobClient = new BlobContainerClientBuilder()
.connectionString("<storage-connection-string>")
.containerName("checkpoints")
.buildAsyncClient();
// Create processor
EventProcessorClient processor = new EventProcessorClientBuilder()
.connectionString("<eventhub-connection-string>", "<event-hub-name>")
.consumerGroup("$Default")
.checkpointStore(new BlobCheckpointStore(blobClient))
.processEvent(eventContext -> {
EventData event = eventContext.getEventData();
System.out.println("Processing: " + event.getBodyAsString());
// Checkpoint after processing
eventContext.updateCheckpoint();
})
.processError(errorContext -> {
System.err.println("Error: " + errorContext.getThrowable().getMessage());
System.err.println("Partition: " + errorContext.getPartitionContext().getPartitionId());
})
.buildEventProcessorClient();
// Start processing
processor.start();
// Keep running...
Thread.sleep(Duration.ofMinutes(5).toMillis());
// Stop gracefully
processor.stop();
バッチ処理
EventProcessorClient processor = new EventProcessorClientBuilder()
.connectionString("<connection-string>", "<event-hub-name>")
.consumerGroup("$Default")
.checkpointStore(new BlobCheckpointStore(blobClient))
.processEventBatch(eventBatchContext -> {
List<EventData> events = eventBatchContext.getEvents();
System.out.printf("Received %d events%n", events.size());
for (EventData event : events) {
// Process each event
System.out.println(event.getBodyAsString());
}
// Checkpoint after batch
eventBatchContext.updateCheckpoint();
}, 50) // maxBatchSize
.processError(errorContext -> {
System.err.println("Error: " + errorContext.getThrowable());
})
.buildEventProcessorClient();
非同期受信
asyncConsumer.receiveFromPartition("0", EventPosition.latest())
.subscribe(
partitionEvent -> {
EventData event = partitionEvent.getData();
System.out.println("Received: " + event.getBodyAsString());
},
error -> System.err.println("Error: " + error),
() -> System.out.println("Complete")
);
Event Hub のプロパティの取得
// Get hub info
EventHubProperties hubProps = producer.getEventHubProperties();
System.out.println("Hub: " + hubProps.getName());
System.out.println("Partitions: " + hubProps.getPartitionIds());
// Get partition info
PartitionProperties partitionProps = producer.getPartitionProperties("0");
System.out.println("Begin sequence: " + partitionProps.getBeginningSequenceNumber());
System.out.println("Last sequence: " + partitionProps.getLastEnqueuedSequenceNumber());
System.out.println("Last offset: " + partitionProps.getLastEnqueuedOffset());
イベント位置
// Start from beginning
EventPosition.earliest()
// Start from end (new events only)
EventPosition.latest()
// From specific offset
EventPosition.fromOffset(12345L)
// From specific sequence number
EventPosition.fromSequenceNumber(100L)
// From specific time
EventPosition.fromEnqueuedTime(Instant.now().minus(Duration.ofHours(1)))
エラー処理
import com.azure.messaging.eventhubs.models.ErrorContext;
.processError(errorContext -> {
Throwable error = errorContext.getThrowable();
String partitionId = errorContext.getPartitionContext().getPartitionId();
if (error instanceof AmqpException) {
AmqpException amqpError = (AmqpException) error;
if (amqpError.isTransient()) {
System.out.println("Transient error, will retry");
}
}
System.err.printf("Error on partition %s: %s%n", partitionId, error.getMessage());
})
リソースのクリーンアップ
// Always close clients
try {
producer.send(batch);
} finally {
producer.close();
}
// Or use try-with-resources
try (EventHubProducerClient producer = new EventHubClientBuilder()
.connectionString(connectionString, eventHubName)
.buildProducerClient()) {
producer.send(events);
}
環境変数
EVENT_HUBS_CONNECTION_STRING=Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=...
EVENT_HUBS_NAME=<event-hub-name>
STORAGE_CONNECTION_STRING=<for-checkpointing>
ベストプラクティス
- EventProcessorClient を使用する:本番環境では、負荷分散とチェックポイント機能を利用できます
- イベントをバッチ処理する:効率的に送信するには
EventDataBatchを使用します - パーティションキー:パーティション内で順序を保証するには、パーティションキーを使用します
- チェックポイント:永続的な処理の後にチェックポイントを設定してください。再生される可能性があるため、コンシューマーは冪等である必要があります
- エラー処理:一時的なエラーは再試行で処理します
- クライアントを閉じる:処理が完了したら、必ずプロデューサー/コンシューマーを閉じてください
トリガーフレーズ
- 「Event Hubs Java」
- 「Azure のイベントストリーミング」
- 「リアルタイムのデータ取り込み」
- 「EventProcessorClient」
- 「イベントハブのプロデューサーとコンシューマー」
- 「パーティション処理」
使用する場面
このスキルは、概要に記載されたワークフローまたはアクションを実行する場合に適用できます。
制限事項
- このスキルは、タスクが上記の範囲に明確に該当する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、処理を止めて確認を求めてください。