1. 概要

このチュートリアルでは、「 Spring CloudNetflixEureka。」を介したクライアント側サービスの検出を紹介します。

クライアント側のサービス検出により、サービスはホスト名とポートをハードコーディングせずに相互に検索および通信できます。このようなアーキテクチャの唯一の「固定小数点」は、サービスレジストリです。各サービスが登録する必要があります。

1つの欠点は、すべてのクライアントがこの固定小数点と対話するために特定のロジックを実装する必要があることです。 これは、実際のリクエストの前に追加のネットワークラウンドトリップを想定しています。

Netflix Eurekaを使用すると、各クライアントは同時にサーバーとして機能し、接続されたピアにステータスを複製できます。 つまり、クライアントはサービスレジストリ内の接続されているすべてのピアのリストを取得し、負荷分散アルゴリズムを介して他のサービスに対してそれ以降のすべての要求を行います。

クライアントの存在について通知を受けるには、クライアントはハートビート信号をレジストリに送信する必要があります。

このチュートリアルの目標を達成するために、3つのマイクロサービスを実装します。

  • サービスレジストリ Eurekaサーバー
  • レジストリに自分自身を登録するRESTサービス( Eurekaクライアント
  • REST サービスをレジストリ対応クライアントとして使用しているWebアプリケーション( Spring Cloud Netflix Feignクライアント

2. ユーレカサーバー

サービスレジストリ用のEurekaサーバーの実装は次のように簡単です。

  1. spring-cloud-starter-netflix-eureka-serverを依存関係に追加します
  2. @SpringBootApplication@EnableEurekaServerの注釈を付けて、Eurekaサーバーを有効にします。
  3. いくつかのプロパティの構成

ステップバイステップでやってみましょう。

まず、新しいMavenプロジェクトを作成し、それに依存関係を設定します。 spring-cloud-starter-parentをこのチュートリアルで説明されているすべてのプロジェクトにインポートしていることに注意してください。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Greenwich.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

最新のSpring Cloudリリースは、Springのプロジェクトドキュメントで確認できます。

次に、メインアプリケーションクラスを作成します。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

最後に、プロパティを YAML 形式で構成するため、application.ymlが構成ファイルになります。

server:
  port: 8761
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

ここでは、アプリケーションポートを構成しています。 Eurekaサーバーのデフォルトは8761です。アプリケーションはサーバーとして機能する必要があるため、組み込みのEurekaクライアントはそれ自体に登録しないように指示しています。

次に、ブラウザで http:// localhost:8761 を指定して、 Eureka ダッシュボードを表示します。このダッシュボードでは、後で登録済みのインスタンスを検査します。

現時点では、ステータスやヘルスインジケーターなどの基本的なインジケーターを確認できます。

3. ユーレカクライアント

のために @ Spring BootApplication 発見を意識するためには、 Springディスカバリークライアント (例えば、 spring-cloud-starter-netflix-eureka-client )私たちにクラスパス。

次に、注釈を付ける必要があります @構成どちらかと @EnableDiscoveryClient また @EnableEurekaClient。 この注釈は、次の場合はオプションであることに注意してください。 spring-cloud-starter-netflix-eureka-client クラスパスへの依存。

後者は、 SpringBootにサービス検出にSpringNetflixEurekaを明示的に使用するように指示します。 クライアントアプリケーションをサンプルライフで満たすために、 spring-boot-starter-webパッケージをpom.xmlに含め、を実装します。 RESTコントローラー。

ただし、最初に依存関係を追加します。 繰り返しになりますが、 spring-cloud-starter-parent の依存関係に任せて、アーティファクトのバージョンを把握することができます。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

ここでは、メインのアプリケーションクラスを実装します。

@SpringBootApplication
@RestController
public class EurekaClientApplication implements GreetingController {

    @Autowired
    @Lazy
    private EurekaClient eurekaClient;

    @Value("${spring.application.name}")
    private String appName;

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }

    @Override
    public String greeting() {
        return String.format(
          "Hello from '%s'!", eurekaClient.getApplication(appName).getName());
    }
}

そしてGreetingControllerインターフェース:

public interface GreetingController {
    @RequestMapping("/greeting")
    String greeting();
}

インターフェイスの代わりに、EurekaClientApplicationクラス内でマッピングを宣言することもできます。 ただし、サーバーとクライアント間でインターフェイスを共有する場合は、インターフェイスが便利です。

次に、登録済みアプリケーションのリストでクライアントを一意に識別するために、構成済みのSpringアプリケーション名を使用してapplication.ymlをセットアップする必要があります。

Spring Boot にランダムなポートを選択させることができます。これは、後でその名前でこのサービスにアクセスするためです。 

最後に、レジストリをどこに配置する必要があるかをクライアントに通知する必要があります。

spring:
  application:
    name: spring-cloud-eureka-client
server:
  port: 0
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
  instance:
    preferIpAddress: true

この種のサービスは後で簡単にスケーラブルにする必要があるため、この方法でEurekaクライアントをセットアップすることにしました。

次に、クライアントを実行し、ブラウザーで http:// localhost:8761 を再度ポイントして、Eurekaダッシュボードに登録ステータスを表示します。 ダッシュボードを使用することで、登録済みのクライアントのホームページを管理目的でダッシュボードにリンクするなど、さらに構成を行うことができます。 ただし、構成オプションはこの記事の範囲を超えています。

4. 偽のクライアント

3つの依存するマイクロサービスでプロジェクトを完成させるために、 Spring Netflix FeignClientを使用してRESTを消費するWebアプリケーションを実装します。

Feign は、インターフェースを使用してエンドポイントと通信する、ディスカバリー対応の SpringRestTemplateと考えてください。 これらのインターフェースは実行時に自動的に実装され、 service-urls の代わりに、service-namesを使用します。

Feign、がないと、 EurekaClient のインスタンスをコントローラーに自動配線する必要があり、service-nameによってとしてサービス情報を受け取ることができます。 Applicationオブジェクト。

このApplicationを使用してこのサービスのすべてのインスタンスのリストを取得し、適切なインスタンスを選択してから、このInstanceInfoを使用してホスト名とポートを取得します。 これにより、任意の httpクライアントで標準のリクエストを実行できます:

@Autowired
private EurekaClient eurekaClient;

@RequestMapping("/get-greeting-no-feign")
public String greeting(Model model) {

    InstanceInfo service = eurekaClient
      .getApplication(spring-cloud-eureka-client)
      .getInstances()
      .get(0);

    String hostName = service.getHostName();
    int port = service.getPort();

    // ...
}

RestTemplate を使用して、 Eureka クライアントサービスに名前でアクセスすることもできますが、このトピックはこの記事の範囲を超えています。

Feign Client プロジェクトをセットアップするには、次の4つの依存関係をpom.xmlに追加します。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Feign Client は、spring-cloud-starter-feignパッケージに含まれています。 これを有効にするには、@Configuration@EnableFeignClientsの注釈を付ける必要があります。 これを使用するには、 @FeignClient( “service-name”)を使用してインターフェイスに注釈を付け、コントローラーに自動配線します。

このようなFeign Clients を作成するための良い方法は、 @RequestMapping アノテーション付きメソッドを使用してインターフェースを作成し、それらを別のモジュールに配置することです。 このようにして、サーバーとクライアント間で共有できます。 サーバー側では、 @Controller として実装でき、クライアント側では、@FeignClientとして拡張および注釈を付けることができます。

さらに、 spring-cloud-starter-eurekaパッケージをプロジェクトに含め、メインアプリケーションクラスに@EnableEurekaClientのアノテーションを付けて有効にする必要があります。

spring-boot-starter-webおよびspring-boot-starter-thymeleaf の依存関係は、ビューを表示するために使用されます。 RESTサービス。

これがFeignClientインターフェースになります。

@FeignClient("spring-cloud-eureka-client")
public interface GreetingClient {
    @RequestMapping("/greeting")
    String greeting();
}

ここでは、コントローラーとして同時に機能するメインアプリケーションクラスを実装します。

@SpringBootApplication
@EnableFeignClients
@Controller
public class FeignClientApplication {
    @Autowired
    private GreetingClient greetingClient;

    public static void main(String[] args) {
        SpringApplication.run(FeignClientApplication.class, args);
    }

    @RequestMapping("/get-greeting")
    public String greeting(Model model) {
        model.addAttribute("greeting", greetingClient.greeting());
        return "greeting-view";
    }
}

これは、ビューのHTMLテンプレートになります。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Greeting Page</title>
    </head>
    <body>
        <h2 th:text="${greeting}"/>
    </body>
</html>

application.yml 構成ファイルは、前の手順とほぼ同じです。

spring:
  application:
    name: spring-cloud-eureka-feign-client
server:
  port: 8080
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}

これで、このサービスを構築して実行できます。 最後に、ブラウザで http:// localhost:8080 / get-greeting を指定すると、次のように表示されます。

Hello from SPRING-CLOUD-EUREKA-CLIENT!

5. ‘ TransportException:既知のサーバーでリクエストを実行できません’

Eurekaサーバーを実行しているときに、次のような例外が発生することがよくあります。

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

基本的に、これはapplication.propertiesまたはapplication.ymlの設定が間違っているために発生します。 Eureka は、構成可能な2つのプロパティをクライアントに提供します。

  • registerWithEureka:このプロパティを true、に設定すると、サーバーの起動中に、組み込みクライアントがEurekaサーバーに自分自身を登録しようとします。
  • fetchRegistry:このプロパティをtrueに設定すると、組み込みクライアントはEurekaレジストリをフェッチしようとします。

Eurekaサーバーを起動するときに、サーバーで自身を構成するために組み込みクライアントを登録したくありません。

上記のプロパティをtrueとしてマークすると(または、デフォルトでは true であるため、構成しないでください)、サーバーの起動中に、組み込みクライアントが登録を試みます。それ自体がEurekaサーバーを使用し、まだ利用できないレジストリをフェッチしようとします。 その結果、TransportExceptionが発生します。

したがって、Eurekaサーバーアプリケーションでこれらのプロパティをtrueとして構成しないでください。 application.ymlに設定する必要がある正しい設定は次のとおりです。

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

6. 結論

この記事では、 Spring Netflix Eurekaサーバーを使用してサービスレジストリを実装し、いくつかのEurekaクライアントを登録する方法を学びました。

手順3のEurekaクライアントはランダムに選択されたポートでリッスンするため、レジストリからの情報がないとその場所を認識できません。 Feign Client とレジストリを使用すると、場所が変わった場合でも、RESTサービスを見つけて利用できます。

最後に、マイクロサービスアーキテクチャでサービスディスカバリを使用する全体像を見ました。

いつものように、GitHubのでソースを見つけることができます。には、docker-composeでコンテナーを作成するために使用するDocker関連ファイルのセットも含まれています。私たちのプロジェクト。