Azure Functions 上で Quarkus を使用してサーバーレス Java アプリをデプロイする
この記事では、Quarkus を使って、サーバーレス Java アプリの開発、ビルド、Azure Functions へのデプロイを行います。 この記事では、Quarkus Funqy と、Java 用の Azure Functions HTTP トリガーに対するその組み込みサポートを使います。 Azure Functions で Quarkus を使うと、Azure Functions の規模と柔軟性で Quarkus のプログラミング モデルの機能を利用できます。 完了したら、Azure Functions でサーバーレス Quarkus アプリケーションを実行し、Azure で引き続きアプリを監視します。
前提条件
- 利用するコンピューターに Azure CLI がインストールされていること。
- Azure アカウント。 Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。
- Java JDK 17 と適切に構成された
JAVA_HOME
。 この記事は Java 17 を想定して書かれましたが、Azure Functions と Quarkus は古いバージョンの Java もサポートしています。 - Apache Maven 3.8.1 以降。
アプリ プロジェクトを作成する
次のコマンドを使って、この記事用のサンプル Java プロジェクトをクローンします。 サンプルは GitHub にあります。
git clone https://github.com/Azure-Samples/quarkus-azure
cd quarkus-azure
git checkout 2023-01-10
cd functions-quarkus
HEAD がデタッチされた状態であることを示すメッセージが表示された場合、このメッセージは無視しても問題ありません。 この記事ではコミットを必要としないため、HEAD がデタッチされた状態が適切です。
サンプル関数を調べます。 functions-quarkus/src/main/java/io/quarkus/GreetingFunction.java ファイルを開きます。
次のコマンドを実行します。 @Funq
注釈を使うと、メソッド (この場合は funqyHello
) がサーバーレス関数になります。
@Funq
public String funqyHello() {
return "hello funqy";
}
Azure Functions の Java には Azure 固有の注釈の独自のセットがありますが、ここで行っているような単純な容量で Azure Functions 上の Quarkus を使うときは、これらの注釈は必要ありません。 Azure Functions の Java 注釈について詳しくは、「Azure Functions の Java 開発者向けガイド」をご覧ください。
特に指定しない限り、関数の名前はメソッド名と同じです。 次のコマンドを使って、パラメーターを持つ関数名を注釈に定義することもできます。
@Funq("alternateName")
public String funqyHello() {
return "hello funqy";
}
名前は重要です。 この記事で後ほど説明するように、それは関数を呼び出すための REST URI の一部になります。
関数をローカルでテストする
ローカル ターミナルで Quarkus の開発モードを実行するには、mvn
を使います。 この方法で Quarkus を実行すると、バックグラウンド コンパイルでライブ リロードできます。 Java ファイルやリソース ファイルを変更してブラウザーを更新すると、これらの変更が自動的に有効になります。
ブラウザーの更新によって、ワークスペースのスキャンがトリガーされます。 スキャンで何らかの変更が検出されると、Java ファイルが再コンパイルされ、アプリケーションが再デプロイされます。 再デプロイされたアプリケーションにより、要求のサービスが行われます。 コンパイルまたはデプロイに問題がある場合は、エラー ページが表示されます。
次の手順では、yourResourceGroupName
をリソース グループ名に置き換えてください。 関数アプリ名は、すべての Azure においてグローバルに一意である必要があります。 リソース グループ名は、サブスクリプション内でグローバルに一意である必要があります。 この記事では、リソース グループ名を関数名の前に付けることで、必要な一意性を実現します。 一意である必要がある名前を作成するには、一意識別子を前に付けることを検討してください。 便利な方法は、自分のイニシャルの後に今日の日付を mmdd
の形式で使用することです。
手順のこの部分ではリソース グループは必要ありませんが、後で必要になります。 わかりやすくするため、Maven プロジェクトではプロパティを定義する必要があります。
Quarkus の開発モードを呼び出します。
cd functions-azure mvn -DskipTests -DresourceGroup=<yourResourceGroupName> quarkus:dev
出力は次のようになります。
... --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ INFO [io.quarkus] (Quarkus Main Thread) quarkus-azure-function 1.0-SNAPSHOT on JVM (powered by Quarkus xx.xx.xx.) started in 1.290s. Listening on: http://localhost:8080 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, funqy-http, smallrye-context-propagation, vertx] -- Tests paused Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
ローカル ターミナルで
CURL
コマンドを使って関数にアクセスします。curl localhost:8080/api/funqyHello
出力は次のようになります。
"hello funqy"
依存関係の挿入を関数に追加する
オープン標準テクノロジの Jakarta EE Contexts and Dependency Injection (CDI) は、Quarkus での依存関係の挿入を提供します。 挿入の一般的な概要と、特に CDI については、Jakarta EE のチュートリアルに関するページをご覧ください。
依存関係の挿入を使う新しい関数を追加します。
functions-quarkus/src/main/java/io/quarkus ディレクトリに GreetingService.java ファイルを作成します。 ファイルのソース コードとして次のコードを使います。
package io.quarkus; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class GreetingService { public String greeting(String name) { return "Welcome to build Serverless Java with Quarkus on Azure Functions, " + name; } }
ファイルを保存します。
GreetingService
は、greeting()
メソッドを実装する挿入可能な Bean です。 このメソッドは、Welcome...
という文字列メッセージとname
パラメーターを返します。既存の functions-quarkus/src/main/java/io/quarkus/GreetingFunction.java ファイルを開きます。 クラスを次のコードに置き換えて、新しい
gService
フィールドとgreeting
メソッドを追加します。package io.quarkus; import javax.inject.Inject; import io.quarkus.funqy.Funq; public class GreetingFunction { @Inject GreetingService gService; @Funq public String greeting(String name) { return gService.greeting(name); } @Funq public String funqyHello() { return "hello funqy"; } }
ファイルを保存します。
ローカル ターミナルで
curl
コマンドを使って新しいgreeting
関数にアクセスします。curl -d '"Dan"' -X POST localhost:8080/api/greeting
出力は次のようになります。
"Welcome to build Serverless Java with Quarkus on Azure Functions, Dan"
重要
ライブ コーディング (開発モードとも呼ばれます) を使うと、アプリを実行しながら変更を行うことができます。 変更が行われると、Quarkus によってアプリが自動的に再コンパイルされて再度読み込まれます。 これは、この記事全体で使用する強力で効率的なスタイルの開発です。
次のステップに進む前に、Ctrl + C キーを押して Quarkus 開発モードを停止します。
Azure にアプリケーションをデプロイする
まだ行っていない場合は、次の az login コマンドを使って Azure サブスクリプションにサインインし、画面上の指示に従います。
az login
Note
複数の Azure テナントがお使いの Azure 資格情報に関連付けられている場合は、サインインするテナントを指定する必要があります。 これは、
--tenant
オプションを使って行うことができます。 (例:az login --tenant contoso.onmicrosoft.com
)。Web ブラウザーでプロセスを続けます。 Web ブラウザーを使えない場合、または Web ブラウザーを開けない場合は、
az login --use-device-code
でデバイス コード フローを使います。正常にサインインすると、ローカル ターミナルに次のように出力されます。
xxxxxxx-xxxxx-xxxx-xxxxx-xxxxxxxxx 'Microsoft' [ { "cloudName": "AzureCloud", "homeTenantId": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx", "id": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx", "isDefault": true, "managedByTenants": [], "name": "Contoso account services", "state": "Enabled", "tenantId": "xxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxx", "user": { "name": "user@contoso.com", "type": "user" } } ]
関数をビルドして Azure にデプロイします。
前のステップで生成した pom.xml ファイルでは、
azure-functions-maven-plugin
が使われています。mvn install
を実行すると、構成ファイルと、azure-functions-maven-plugin
で必要なステージング ディレクトリが生成されます。yourResourceGroupName
の場合は、前に使った値を使います。mvn clean install -DskipTests -DtenantId=<your tenantId from shown previously> -DresourceGroup=<yourResourceGroupName> azure-functions:deploy
デプロイの間に、Azure にサインインします。
azure-functions-maven-plugin
プラグインは、プロジェクトがデプロイされるたびに Azure へのサインインを要求するように構成されています。 ビルドの間に、次のような出力が表示されます。[INFO] Auth type: DEVICE_CODE To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code AXCWTLGMP to authenticate.
出力で示されているように、ブラウザーと提供されたデバイス コードを使って Azure への認証を行います。 その他の多くの認証および構成オプションを使用できます。
azure-functions-maven-plugin
の完全な参照ドキュメントについては、「Azure Functions: 構成の詳細」をご覧ください。認証の後で、ビルドが続けられて完了するはずです。 出力に最後近くに
BUILD SUCCESS
が含まれていることを確認します。Successfully deployed the artifact to https://quarkus-demo-123451234.azurewebsites.net
Azure で関数をトリガーする URL を、出力ログで見つけることもできます。
[INFO] HTTP Trigger Urls: [INFO] quarkus : https://quarkus-azure-functions-http-archetype-20220629204040017.azurewebsites.net/api/{*path}
デプロイが完了するまで、しばらく時間がかかります。 それまでの間に、Azure portal で Azure Functions を調べてみましょう。
Azure でサーバーレス関数にアクセスして監視する
ポータルにサインインし、Azure CLI で使ったのと同じテナントとサブスクリプションを選んでいることを確認します。
Azure portal の上部にある検索バーに「関数アプリ」と入力して、Enter キーを押します。 関数アプリがデプロイされ、
<yourResourceGroupName>-function-quarkus
という名前で表示されます。関数アプリを選ぶと、[場所]、[サブスクリプション]、[URL]、[メトリック]、[App Service プラン] などの詳細情報が表示されます。 次に、[URL] の値を選びます。
ウェルカム ページに、関数アプリが "稼働中" であると表示されることを確認します。
ローカル ターミナルで次の
curl
コマンドを使ってgreeting
関数を呼び出します。重要
YOUR_HTTP_TRIGGER_URL
を、Azure portal または出力で見つけた独自の関数 URL に置き換えます。curl -d '"Dan on Azure"' -X POST https://YOUR_HTTP_TRIGGER_URL/api/greeting
出力は次のようになります。
"Welcome to build Serverless Java with Quarkus on Azure Functions, Dan on Azure"
次の
curl
コマンドを使って、他の関数 (funqyHello
) にアクセスすることもできます。curl https://YOUR_HTTP_TRIGGER_URL/api/funqyHello
出力は、前に見たものと同じになるはずです。
"hello funqy"
Azure portal でメトリックの基本的な機能を試したい場合は、シェルの
for
ループ内で関数を呼び出してみてください。for i in {1..100}; do curl -d '"Dan on Azure"' -X POST https://YOUR_HTTP_TRIGGER_URL/api/greeting; done
しばらくすると、ポータルにいくつかのメトリック データが表示されます。
ポータルで Azure 関数を開いたので、ポータルからアクセスできる他の機能を次に示します。
- Azure 関数のパフォーマンスを監視します。 詳しくは、「Azure Functions の監視」をご覧ください。
- テレメトリを調べます。 詳しくは、「Application Insights で Azure Functions のテレメトリを分析する」をご覧ください。
- ログを設定します。 詳しくは、「Azure Functions で実行ログのストリーミングを有効にする」をご覧ください。
リソースをクリーンアップする
これらのリソースが不要な場合は、次のコマンドを実行することでこれらを削除できます。
az group delete --name <yourResourceGroupName> --yes
次のステップ
この記事で学習した内容は次のとおりです。
- Quarkus の開発モードを実行します。
azure-functions-maven-plugin
を使って、Funqy アプリを Azure Functions にデプロイします。- ポータルで関数のパフォーマンスを調べます。
Azure Functions と Quarkus について詳しくは、次の記事とリファレンスをご覧ください。