Tanzu Service Registry を使用する

Note

Azure Spring Apps は、Azure Spring Cloud サービスの新しい名前です。 サービスの名前は新しくなりましたが、スクリーンショット、ビデオ、図などの資産の更新に取り組んでいる間、場所によってはしばらく古い名前が表示されます。

この記事の適用対象:❌ 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 とサービス B を作成、デプロイ、登録する手順を示す図。

これらの手順は、以下のセクションで詳しく説明します。

  1. サービス A を作成します。
  2. サービス A を Azure Spring Apps にデプロイし、サービス レジストリに登録します。
  3. サービス B を作成し、サービス A を呼び出すための実装を行います。
  4. サービス B をデプロイし、サービス レジストリに登録します。
  5. サービス 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 と必要な設定を示しています。

Spring Initializer ページのスクリーンショット。必須の設定が表示されています。

次に、[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 からもアプリケーションのバインドを設定できます。

Azure portal のスクリーンショット。[サービス レジストリ] ページで [アプリ バインド] ドロップダウンが強調表示されています。

Note

サービス レジストリの状態が変更されたとき、それらの変更がすべてのアプリケーションに反映されるまで数分かかります。

バインド/バインド解除の状態を変更した場合、アプリケーションを再起動または再デプロイする必要があります。

次のコマンドを使用して、新しいアプリを作成するときにアプリケーションをサービス レジストリに直接バインドすることを選択できるようになりました。

az spring app create \ 
    --resource-group <resource-group> \ 
    --service <service-name> \ 
    --name <app-name> \ 
    --bind-service-registry

次のスクリーンショットに示されているように、Azure portal からもアプリケーションをサービス レジストリにバインドできます。

[バインド] ドロップダウンが強調表示された [アプリの作成] ページを示す 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.defaultZoneJAVA_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 を使用してサービス レジストリを有効または無効にするには、次の手順に従います。

  1. サービス リソースに移動し、[サービス レジストリ] を選択します。
  2. [管理] を選択します。
  3. [サービス レジストリを有効にする] を選択または選択解除し、[保存] を選択します。
  4. [サービス レジストリ] ページで、サービス レジストリの状態を表示できるようになりました。

次のステップ