Tanzu Service Registry を使用する
Note
Basic、Standard、Enterprise プランは、2025 年 3 月中旬以降非推奨になり、廃止期間は 3 年間です。 Azure Container Apps に移行することをお勧めします。 詳細については、「Azure Spring Apps の廃止のお知らせ」を参照してください。
Standard 従量課金と専用プランは、2024 年 9 月 30 日以降に非推奨になり、6 か月後に完全にシャットダウンされます。 Azure Container Apps に移行することをお勧めします。 詳細については、「Azure Spring Apps の Standard 従量課金および専用プランを Azure Container Apps に移行する」を参照してください。
この記事の適用対象: ❎ Basic/Standard ✅ Enterprise
この記事では、Azure Spring Apps Enterprise プランで VMware Tanzu Service Registry を使用する方法について説明します。
Tanzu Service Registry は、商用 VMware Tanzu コンポーネントの 1 つです。 このコンポーネントは、"サービス検出" 設計パターンをアプリケーションに適用するのに役立ちます。
サービス検出は、マイクロサービス アーキテクチャの主要な概念の 1 つです。 サービス検出を使用しない場合、サービスの各クライアントを手動で構成するか、何らかの形式のアクセス規則を採用する必要があります。 このプロセスは困難な場合があり、運用環境では構成と規則が脆弱になる可能性があります。 代わりに、Tanzu Service Registry を使用して、アプリケーションで登録済みサービスを動的に検出して呼び出すことができます。
Azure Spring Apps Enterprise プランでは、サービス レジストリを自分で作成または開始する必要ありません。 Azure Spring Apps Enterprise プランのインスタンスを作成するときに Tanzu Service Registry を選択することで、これを使用できます。
前提条件
- Tanzu Service Registry が有効になっている Azure Spring Apps Enterprise プランのインスタンスが既にプロビジョニングされていること。 詳しくは、「クイックスタート: Enterprise プランを使用してアプリをビルドし Azure Spring Apps にデプロイする」をご参照ください。
- Azure Spring Apps Enterprise プランの拡張機能。 次のコマンドを使用して、以前のバージョンを削除し、最新の Enterprise プランの拡張機能をインストールします。 以前に
spring-cloud
拡張機能をインストールした場合は、構成とバージョンの不一致を回避するためにそれをアンインストールします。az extension add --upgrade --name spring az extension remove --name spring-cloud
サービス レジストリを使用するアプリケーションを作成する
この記事では、2 つのサービスを作成し、それらを Azure Spring Apps サービス レジストリに登録します。 登録後、一方のサービスでサービス レジストリを使用してもう一方のサービスを検出し、呼び出すことができます。 次の図は、必要な手順をおおまかに示しています。
これらの手順は、以下のセクションで詳しく説明します。
- サービス A を作成します。
- サービス A を Azure Spring Apps にデプロイし、サービス レジストリに登録します。
- サービス B を作成し、サービス A を呼び出すための実装を行います。
- サービス B をデプロイし、サービス レジストリに登録します。
- サービス B を介してサービス A を呼び出します。
環境変数を作成する
この記事では、次の環境変数を使用します。 これらの変数は、Azure Spring Apps Enterprise プランのインスタンスを作成したときに使用した値に設定します。
Variable | 説明 |
---|---|
$RESOURCE_GROUP | リソース グループ名。 |
$AZURE_SPRING_APPS_NAME | Azure Spring Apps インスタンスの名前。 |
Spring Boot を使用してサービス A を作成する
Spring Initializr に移動して、サンプルのサービス A を作成します。このリンクでは、次の URL を使用して設定が初期化されます。
https://start.spring.io/#!type=maven-project&language=java&packaging=jar&groupId=com.example&artifactId=Sample%20Service%20A&name=Sample%20Service%20A&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.Sample%20Service%20A&dependencies=web,cloud-eureka
次のスクリーンショットは、Spring Initializr と必要な設定を示しています。
次に、[GENERATE] (生成) を選択して、次のディレクトリ構造を含む Spring Boot のサンプル プロジェクトを取得します。
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── Sample
│ │ └── Service
│ │ └── A
│ │ └── SampleServiceAApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── com
└── example
└── Sample
└── Service
└── A
└── SampleServiceAApplicationTests.java
サービス レジストリ クライアント (Eureka クライアント) の依存ライブラリの構成を確認する
次に、プロジェクトの pom.xml ファイルに次の依存関係が含まれていることを確認します。 依存関係がない場合は追加します。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
サービス レジストリ クライアントを実装する
@EnableEurekaClient
注釈を SampleServiceAApplication.java ファイルに追加して、これを Eureka クライアントとして構成します。
package com.example.Sample.Service.A;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class SampleServiceAApplication {
public static void main(String[] args) {
SpringApplication.run(SampleServiceAApplication.class, args);
}
}
テスト用の REST エンドポイントを作成する
これで、このサービスをサービス レジストリに登録できるようになりましたが、サービス エンドポイントを実装するまで、このサービスを検証できません。 外部サービスが呼び出すことができる RESTful エンドポイントを作成するには、次のコードを使用して ServiceAEndpoint.java ファイルをプロジェクトに追加します。
package com.example.Sample.Service.A;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ServiceAEndpoint {
@GetMapping("/serviceA")
public String getServiceA(){
return "This is a result of Service A";
}
@GetMapping("/env")
public Map<String, String> getEnv(){
Map<String, String> env = System.getenv();
return env;
}
}
Spring Boot アプリケーションをビルドする
簡単なサービスが完成したので、次のコマンドを実行してそのソース コードをコンパイルしてビルドします。
mvn clean package
サービス A をデプロイし、サービス レジストリに登録する
このセクションでは、サービス A を Azure Spring Apps Enterprise プラン インスタンスにデプロイし、それをサービス レジストリに登録する方法について説明します。
Azure Spring Apps アプリケーションを作成する
最初に、次のコマンドを使用して Azure Spring Apps でアプリケーションを作成します。
az spring app create \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--name serviceA \
--instance-count 1 \
--memory 2Gi \
--assign-endpoint
--assign-endpoint
引数により、検証用のパブリック IP が付与され、外部ネットワークからアクセスできるようになります。
アプリからサービス レジストリに接続する
Spring Boot を使用してサービス インスタンスを作成し、Azure Spring Apps でアプリケーションを作成したら、アプリケーションをデプロイして操作を確認します。 ただし、その前に、アプリケーションをサービス レジストリにバインドして、レジストリから接続情報を取得できるようにする必要があります。
通常、Eureka クライアントでは、サーバーに接続できるように、Spring Boot アプリケーションの application.properties 構成ファイルに次の接続情報設定を記述する必要があります。
eureka.client.service-url.defaultZone=http://eureka:8761/eureka/
ただし、アプリケーションにこれらの設定を直接記述する場合、サービス レジストリ サーバーの変更のたびに、プロジェクトを再編集して再ビルドする必要があります。 この作業を回避するために、Azure Spring Apps では、サービス レジストリにバインドすることで、アプリケーションでサービス レジストリから接続情報を取得できます。 具体的には、アプリケーションをサービス レジストリにバインドした後、Java 環境変数からサービス レジストリの接続情報 (eureka.client.service-url.defaultZone
) を取得できます。 このようにして、アプリケーションの起動時に環境変数の内容を読み込むことで、サービス レジストリに接続できます。
実際には、次の環境変数が JAVA_TOOL_OPTIONS
変数に追加されます。
-Deureka.client.service-url.defaultZone=https://$AZURE_SPRING_APPS_NAME.svc.azuremicroservices.io/eureka/default/eureka
サービスをサービス レジストリにバインドする
次のコマンドを使用して、サービスを Azure サービス レジストリにバインドし、サーバーに接続できるようにします。
az spring service-registry bind \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--app serviceA
次のスクリーンショットに示されているように、Azure portal からもアプリケーションのバインドを設定できます。
Note
サービス レジストリの状態が変更されたとき、それらの変更がすべてのアプリケーションに反映されるまで数分かかります。
バインド/バインド解除の状態を変更した場合、アプリケーションを再起動または再デプロイする必要があります。
次のコマンドを使用して、新しいアプリを作成するときにアプリケーションをサービス レジストリに直接バインドすることを選択できるようになりました。
az spring app create \
--resource-group <resource-group> \
--service <service-name> \
--name <app-name> \
--bind-service-registry
次のスクリーンショットに示されているように、Azure portal からもアプリケーションをサービス レジストリにバインドできます。
アプリケーションを Azure Spring Apps にデプロイする
アプリケーションをバインドしたので、Spring Boot のアーティファクト ファイル Sample-Service-A-A-0.0.1-SNAPSHOT.jar を Azure Spring Apps にデプロイします。 デプロイするには、次のコマンドを使用します。
az spring app deploy \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--name serviceA \
--artifact-path ./target/Sample-Service-A-0.0.1-SNAPSHOT.jar \
--jvm-options="-Xms1024m -Xmx1024m"
次のコマンドを使用して、デプロイが成功したかどうかを確認します。
az spring app list \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--output table
このコマンドでは、次の例のような出力が生成されます。
Name Location ResourceGroup Public Url Production Deployment Provisioning State CPU Memory Running Instance Registered Instance Persistent Storage Bind Service Registry Bind Application Configuration Service
------------------------ ------------- ---------------------- ------------------------------------------------------------------- ----------------------- -------------------- ----- -------- ------------------ --------------------- -------------------- ----------------------- ----------------------------------------
servicea southeastasia $RESOURCE_GROUP https://$AZURE_SPRING_APPS_NAME-servicea.azuremicroservices.io default Succeeded 1 2Gi 1/1 N/A - default -
サービス A アプリケーションが実行されていることを確認する
前のコマンドの出力には、サービスのパブリック URL が含まれています。 RESTful エンドポイントにアクセスするには、次のコマンドのように、/serviceA
を URL に追加します。
curl https://$AZURE_SPRING_APPS_NAME-servicea.azuremicroservices.io/serviceA
このコマンドでは次の出力が生成されます。
This is a result of Service A
サービス A には、環境変数の一覧を表示する RESTful エンドポイントが含まれています。 次のコマンドのように、/env
を使用してエンドポイントにアクセスし、環境変数を確認します。
curl https://$AZURE_SPRING_APPS_NAME-servicea.azuremicroservices.io/env
このコマンドでは次の出力が生成されます。
"JAVA_TOOL_OPTIONS":"-Deureka.client.service-url.defaultZone=https://$AZURE_SPRING_APPS_NAME.svc.azuremicroservices.io/eureka/default/eureka
eureka.client.service-url.defaultZone
が JAVA_TOOL_OPTIONS
に追加されていることがわかります。 このようにして、アプリケーションでサービスをサービス レジストリに登録して、他のサービスから利用できるようにすることができます。
これで、Azure Spring Apps のサービス レジストリ (Eureka サーバー) にサービスを登録できます。 他のサービスは、サービス レジストリを使用してそのサービスにアクセスできます。
サービス レジストリを介してサービス A にアクセスする新しいサービス B を実装する
Spring Boot を使用してサービス B を実装する
Spring Initializr に移動して、サービス B の新しいプロジェクトを作成します。このリンクでは、次の URL を使用して設定が初期化されます。
https://start.spring.io/#!type=maven-project&language=java&packaging=jar&groupId=com.example&artifactId=Sample%20Service%20B&name=Sample%20Service%20B&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.Sample%20Service%20B&dependencies=web,cloud-eureka
次に、[GENERATE] (生成) を選択して新しいプロジェクトを取得します。
サービス B をサービス レジストリ クライアント (Eureka クライアント) として実装する
サービス A と同様に、@EnableEurekaClient
注釈をサービス B に追加して、Eureka クライアントとして構成します。
package com.example.Sample.Service.B;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class SampleServiceBApplication {
public static void main(String[] args) {
SpringApplication.run(SampleServiceBApplication.class, args);
}
}
サービス B にサービス エンドポイントを実装する
次に、サービス A を呼び出す新しいサービス エンドポイント (/invoke-serviceA
) を実装します。次のコードを使用して 、ServiceBEndpoint.java ファイルをプロジェクトに追加します。
package com.example.Sample.Service.B;
import java.util.List;
import java.util.stream.Collectors;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ServiceBEndpoint {
@Autowired
private EurekaClient discoveryClient;
@GetMapping(value = "/invoke-serviceA")
public String invokeServiceA()
{
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://servicea/serviceA",String.class);
return "INVOKE SERVICE A FROM SERVICE B: " + response;
}
@GetMapping(value = "/list-all")
public List<String> listsAllServices() {
Applications applications = discoveryClient.getApplications();
List<Application> registeredApplications = applications.getRegisteredApplications();
List<String> appNames = registeredApplications.stream().map(app -> app.getName()).collect(Collectors.toList());
return appNames;
}
}
この例では、簡素化するために RestTemplate
を使用しています。 このエンドポイントは、サービス B によって呼び出されたことを示す別の文字列 (INVOKE SERVICE A FROM SERVICE B: "
) を含む応答文字列を返します。
この例では、検証のために別のエンドポイント (/list-all
) も実装します。 この実装により、サービスがサービス レジストリと正しく通信するか確認されます。 このエンドポイントを呼び出して、サービス レジストリに登録されているアプリケーションの一覧を取得できます。
この例では、サービス A を http://servicea
として呼び出します。 サービス名は、Azure Spring Apps アプリケーションの作成時に指定した名前です (例: az spring app create --name ServiceA
)。アプリケーション名は、サービス レジストリに登録したサービス名と一致するため、サービス名は簡単に管理できます。
サービス B をビルドする
次のコマンドを使用して、プロジェクトをビルドします。
mvn clean package
サービス B を Azure Spring Apps にデプロイする
サービス B をデプロイするために、次のコマンドを使用して、Azure Spring Apps でアプリケーションを作成します。
az spring app create \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--name serviceB \
--instance-count 1 \
--memory 2Gi \
--assign-endpoint
次に、次のコマンドを使用して、アプリケーションをサービス レジストリにバインドします。
az spring service-registry bind \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--app serviceB
次に、次のコマンドを使用して、サービスをデプロイします。
az spring app deploy \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--name serviceB \
--artifact-path ./target/Sample-Service-B-0.0.1-SNAPSHOT.jar \
--jvm-options="-Xms1024m -Xmx1024m"
次に、次のコマンドを使用して、アプリケーションの状態を確認します。
az spring app list \
--resource-group $RESOURCE_GROUP \
--service $AZURE_SPRING_APPS_NAME \
--output table
サービス A とサービス B が正しくデプロイされている場合、このコマンドにより、次の例のような出力が生成されます。
Name Location ResourceGroup Public Url Production Deployment Provisioning State CPU Memory Running Instance Registered Instance Persistent Storage Bind Service Registry Bind Application Configuration Service
-------- ------------- ---------------------- --------------------------------------------------------------- ----------------------- -------------------- ----- -------- ------------------ --------------------- -------------------- ----------------------- ----------------------------------------
servicea southeastasia SpringCloud-Enterprise https://$AZURE_SPRING_APPS_NAME-servicea.azuremicroservices.io default Succeeded 1 2Gi 1/1 1/1 - default -
serviceb southeastasia SpringCloud-Enterprise https://$AZURE_SPRING_APPS_NAME-serviceb.azuremicroservices.io default Succeeded 1 2Gi 1/1 1/1 - default -
サービス B からサービス A を呼び出す
前のコマンドの出力には、サービスのパブリック URL が含まれています。 RESTful エンドポイントにアクセスするには、次のコマンドのように、/invoke-serviceA
を URL に追加します。
curl https://$AZURE_SPRING_APPS_NAME-serviceb.azuremicroservices.io/invoke-serviceA
このコマンドでは次の出力が生成されます。
INVOKE SERVICE A FROM SERVICE B: This is a result of Service A
サービス レジストリからいくつかの情報を取得する
最後に、/list-all
エンドポイントにアクセスし、サービス レジストリからいくつか情報を取得します。 次のコマンドにより、サービス レジストリに登録されているサービスの一覧が取得されます。
curl https://$AZURE_SPRING_APPS_NAME-serviceb.azuremicroservices.io/list-all
このコマンドでは次の出力が生成されます。
["SERVICEA","EUREKA-SERVER","SERVICEB"]
このようにして、必要に応じてプログラムから詳細情報を取得できます。
サービスの作成後にサービス レジストリを有効または無効にする
Azure portal または Azure CLI を使用して、サービスの作成後にサービス レジストリを有効または無効にすることができます。 サービス レジストリを無効にする前に、すべてのアプリのバインドを解除する必要があります。
Azure portal を使用してサービス レジストリを有効または無効にするには、次の手順に従います。
- サービス リソースに移動し、[サービス レジストリ] を選択します。
- [管理] を選択します。
- [サービス レジストリを有効にする] を選択または選択解除し、[保存] を選択します。
- [サービス レジストリ] ページで、サービス レジストリの状態を表示できるようになりました。