Zookeeper によるサービス検出

サービスディスカバリは、マイクロサービスベースのアーキテクチャの重要な原則の 1 つです。各クライアントや何らかの形式の規則を手動で構成しようとすると、実行が難しく、脆弱になる可能性があります。学芸員 (英語) (Zookeeper の Java ライブラリ) は、サービスディスカバリ拡張機能 [Apache] (英語) を通じてサービス検出を提供します。Spring Cloud Zookeeper は、サービスの登録と検出にこの拡張機能を使用します。

アクティブ化

org.springframework.cloud:spring-cloud-starter-zookeeper-discovery への依存関係を含めると、Spring Cloud Zookeeper Discovery をセットアップする自動構成が有効になります。

Web 機能の場合は、org.springframework.boot:spring-boot-starter-web を含める必要があります。
Zookeeper のバージョン 3.4 を使用する場合は、ここで説明されているように依存関係を含める方法を変更する必要があります。

Zookeeper への登録

クライアントが Zookeeper に登録すると、それ自体に関するメタデータ (ホストとポート、ID、名前など) が提供されます。

次の例は、Zookeeper クライアントを示しています。

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}
前述の例は、通常の Spring Boot アプリケーションです。

Zookeeper が localhost:2181 以外の場所にある場合は、次の例に示すように、構成でサーバーの場所を指定する必要があります。

application.yml
spring:
  cloud:
    zookeeper:
      connect-string: localhost:2181
Spring Cloud Zookeeper 構成を使用する場合、前の例に示されている値は application.yml ではなく bootstrap.yml である必要があります。

デフォルトのサービス名、インスタンス ID、ポート ( Environment から取得) は、それぞれ ${spring.application.name}、Spring コンテキスト ID、および ${server.port} です。

クラスパス上に spring-cloud-starter-zookeeper-discovery があると、アプリは Zookeeper 「サービス」 (つまり、アプリ自体を登録します) と「クライアント」 (つまり、Zookeeper にクエリを実行して他のサービスを見つけることができます) の両方になります。

Zookeeper Discovery Client を無効にする場合は、spring.cloud.zookeeper.discovery.enabled を false に設定します。

DiscoveryClient の使用

Spring Cloud は、物理 URL の代わりに論理サービス名を使用して、OpenFeign (REST クライアントビルダー)、RestTemplateSpring Cloud ロードバランサ経由の WebClient をサポートします。

次の例に示すように、Netflix に固有ではない検出クライアント用の単純な API を提供する org.springframework.cloud.client.discovery.DiscoveryClient を使用することもできます。

@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
    if (list != null && list.size() > 0 ) {
        return list.get(0).getUri().toString();
    }
    return null;
}