JMSの使用
このガイドでは、QuarkusアプリケーションがApache Qpid JMS AMQPクライアント、またはApache ActiveMQ Artemis JMSクライアントを介してJMSメッセージングを使用する方法を説明します。
この技術は、previewと考えられています。 preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリスト や GitHub の課題管理 で受け付けています。 とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。 |
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 11+ がインストールされ、
JAVA_HOME
が適切に設定されていること -
Apache Maven 3.9.1
-
使用したい場合は、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
-
実行中のArtemisサーバー、またはDockerでの起動
アーキテクチャ
In this guide, we are going to generate (random) prices in one component. These prices are written to a queue (prices
) using a JMS client. Another component reads from the prices
queue and stores the latest price. The data can be fetched from a browser using a fetch button from a Jakarta REST resource.
このガイドは、すぐ下で説明しているApache Qpid JMS AMQPクライアントを使うか、 後で詳しく説明するように 、Apache ActiveMQ Artemis JMSクライアントでいくつかの異なる設定を行うことができます。
Qpid JMS - AMQP
以下の詳細な手順では、 Quarkus Qpid JMSエクステンション を使用して Apache Qpid JMS クライアントを使用します。Qpid JMSは、ワイヤプロトコルとしてAMQP 1.0 ISO標準を使用しているため、ActiveMQ Artemis、ActiveMQ 5、Qpid Broker-J、Qpid Dispatchルーター、Azure Service Busなど、さまざまなAMQP 1.0サーバーやサービスで使用することができます。
ソリューション
次のセクションで紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。
Git リポジトリをクローンします。 git clone https://github.com/amqphub/quarkus-qpid-jms-quickstart.git
または アーカイブ をダウンロードします。
Mavenプロジェクトの作成
まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します:
このコマンドは、quarkus-qpid-jmsエクステンションをインポートした新しいプロジェクトを生成します:
<dependency>
<groupId>org.amqphub.quarkus</groupId>
<artifactId>quarkus-qpid-jms</artifactId>
</dependency>
implementation("org.amqphub.quarkus:quarkus-qpid-jms")
ブローカーの開始
次に、AMQPブローカーが必要です。この場合はActiveMQ Artemisサーバーを使用します。 Apache ArtemisのWebサイト の手順に従うか、 ArtemisCloud コンテナイメージを使用し、docker経由でブローカーを起動します:
docker run -it --rm -p 8161:8161 -p 61616:61616 -p 5672:5672 -e AMQ_USER=quarkus -e AMQ_PASSWORD=quarkus quay.io/artemiscloud/activemq-artemis-broker:0.1.4
価格のプロデューサー
以下の内容の src/main/java/org/acme/jms/PriceProducer.java
ファイルを作成します:
package org.acme.jms;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSContext;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
/**
* A bean producing random prices every 5 seconds and sending them to the prices JMS queue.
*/
@ApplicationScoped
public class PriceProducer implements Runnable {
@Inject
ConnectionFactory connectionFactory;
private final Random random = new Random();
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
void onStart(@Observes StartupEvent ev) {
scheduler.scheduleWithFixedDelay(this, 0L, 5L, TimeUnit.SECONDS);
}
void onStop(@Observes ShutdownEvent ev) {
scheduler.shutdown();
}
@Override
public void run() {
try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
context.createProducer().send(context.createQueue("prices"), Integer.toString(random.nextInt(100)));
}
}
}
価格のコンシューマー
価格のコンシューマーはJMSから価格を読み取り、最後の1つを保存します。以下の内容で src/main/java/org/acme/jms/PriceConsumer.java
ファイルを作成します:
package org.acme.jms;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSConsumer;
import jakarta.jms.JMSContext;
import jakarta.jms.JMSException;
import jakarta.jms.Message;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
/**
* A bean consuming prices from the JMS queue.
*/
@ApplicationScoped
public class PriceConsumer implements Runnable {
@Inject
ConnectionFactory connectionFactory;
private final ExecutorService scheduler = Executors.newSingleThreadExecutor();
private volatile String lastPrice;
public String getLastPrice() {
return lastPrice;
}
void onStart(@Observes StartupEvent ev) {
scheduler.submit(this);
}
void onStop(@Observes ShutdownEvent ev) {
scheduler.shutdown();
}
@Override
public void run() {
try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
JMSConsumer consumer = context.createConsumer(context.createQueue("prices"));
while (true) {
Message message = consumer.receive();
if (message == null) return;
lastPrice = message.getBody(String.class);
}
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
}
価格のリソース
Finally, let’s create a simple Jakarta REST resource to show the last price. Create the src/main/java/org/acme/jms/PriceResource.java
file with the following content:
package org.acme.jms;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
/**
* A simple resource showing the last price.
*/
@Path("/prices")
public class PriceResource {
@Inject
PriceConsumer consumer;
@GET
@Path("last")
@Produces(MediaType.TEXT_PLAIN)
public String last() {
return consumer.getLastPrice();
}
}
HTMLページ
最後に、変換された価格をSSEを使って読み込むHTMLページです。
以下の内容の src/main/resources/META-INF/resources/prices.html
ファイルを作成します :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prices</title>
<link rel="stylesheet" type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly.min.css">
<link rel="stylesheet" type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly-additions.min.css">
</head>
<body>
<div class="container">
<h2>Last price</h2>
<div class="row">
<p class="col-md-12"><button id="fetch">Fetch</button>The last price is <strong><span id="content">N/A</span> €</strong>.</p>
</div>
</div>
</body>
<script>
document.getElementById("fetch").addEventListener("click", function() {
fetch("/prices/last").then(function (response) {
response.text().then(function (text) {
document.getElementById("content").textContent = text;
})
})
})
</script>
</html>
特筆すべきものは何もありません。フェッチするたびにページが更新されます。
Qpid JMSのプロパティーの設定
ConnectionFactoryを注入する際にエクステンションで使用するQpid JMSプロパティーを設定する必要があります。
これは、 src/main/resources/application.properties
ファイルで行います。
# Configures the Qpid JMS properties.
quarkus.qpid-jms.url=amqp://localhost:5672
quarkus.qpid-jms.username=quarkus
quarkus.qpid-jms.password=quarkus
設定の詳細については、 Quarkus Qpid JMS のドキュメントを参照してください。
実行
手順に従うことで、Artemis サーバーを起動できます。あとは、アプリケーションを使用して実行するだけです:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
ブラウザーで http://localhost:8080/prices.html
を開いてください。
ネイティブ実行
以下でネイティブ実行可能ファイルをビルドすることができます:
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.package.type=native
あるいは、GraalVMをインストールしていない場合は、代わりにDockerを使ってネイティブ実行可能ファイルをビルドすることもできます:
quarkus build --native --no-tests -Dquarkus.native.container-build=true
# The --no-tests flag is required only on Windows and macOS.
./mvnw install -Dnative -DskipTests -Dquarkus.native.container-build=true
./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true
次に、以下を実行してください:
./target/jms-quickstart-1.0.0-SNAPSHOT-runner
ブラウザーで http://localhost:8080/prices.html
を開いてください。
Artemis JMS
The above steps detailed using the Qpid JMS AMQP client, however the guide can also be used with the Artemis JMS client. Many of the individual steps are exactly as previously detailed above for Qpid JMS. The individual component code is the same. The only differences are in the dependency for the initial project creation, and the configuration properties used. These changes are detailed below and should be substituted for the equivalent step during the sequence above.
ソリューション
完成した例に進むことができます。
Gitレポジトリをクローンする: git clone https://github.com/quarkusio/quarkus-quickstarts.git
か、 アーカイブ をダウンロードします。
Artemis JMS ソリューションは jms-quickstart
ディレクトリ にあります。
Mavenプロジェクトの作成
以下のコマンドで新規プロジェクトを作成します:
これにより quarkus-artemis-jmsエクステンションをインポートした新しいプロジェクトが作成されます:
<dependency>
<groupId>io.quarkiverse.artemis</groupId>
<artifactId>quarkus-artemis-jms</artifactId>
</dependency>
implementation("io.quarkiverse.artemis:quarkus-artemis-jms")
プロジェクトが作成されたので、上記の詳細な手順で ブローカーの起動 から再開し、 application.properties
ファイルを設定するところまで進めることができます。
Artemisのプロパティーの設定
Artemis の接続プロパティーを設定する必要があります。これは src/main/resources/application.properties
ファイルで行います。
# Configures the Artemis properties.
quarkus.artemis.url=tcp://localhost:61616
quarkus.artemis.username=quarkus
quarkus.artemis.password=quarkus
Artemisのプロパティが設定された状態で、 実行 から上記の手順を再開することができます。
設定リファレンス
Artemis JMSクライアントの設定方法については、 エクステンションのドキュメントを参照してください。