Spring Cloud Netflix入門–ユーレカ
1. 概要
このチュートリアルでは、「Spring Cloud Netflix Eureka」を介したclient-side serviceディスカバリーを紹介します。
Client-side service discovery allows services to find and communicate with each other without hard-coding hostname and port.このようなアーキテクチャの唯一の「固定小数点」は、各サービスが登録する必要のあるservice registryで構成されます。
欠点は、すべてのクライアントがこの固定小数点と対話するために特定のロジックを実装する必要があることです。 これは、実際の要求の前に追加のネットワークラウンドトリップを想定しています。
Netflix Eurekaを使用すると、各クライアントは同時にサーバーとして機能し、接続されたピアにそのステータスを複製できます。 つまり、クライアントは、service registryの接続されているすべてのピアのリストを取得し、負荷分散アルゴリズムを介して他のサービスに対してそれ以降のすべての要求を行います。
クライアントの存在について通知を受けるには、レジストリにハートビート信号を送信する必要があります。
この記事の目標を達成するために、3つのmicroservicesを実装します。
-
service registry(Eureka Server)、
-
レジストリ(Eureka Client)に自分自身を登録するRESTサービスと
-
RESTサービスをレジストリ対応クライアント(Spring Cloud Netflix *Feign Client*)として使用しているWebアプリケーション。
==さらに読む:
Spring Cloud Netflixのガイド– Hystrix
この記事では、Spring Cloud Hystrixを使用して、アプリケーションロジックにフォールバックを設定する方法を示します。
Zuulプロキシを使用したSpring REST
Spring REST APIでのZuulプロキシの使用を調査し、CORSおよびブラウザーの同一生成元ポリシー制約を回避します。
2. ユーレカサーバー
サービスレジストリのEureka Serverの実装は、次のように簡単です。
-
@EnableEurekaServerで注釈を付けて、@SpringBootApplicationでEurekaサーバーを有効にします
-
いくつかのプロパティを設定する
ただし、段階的に実行します。
まず、新しいMavenプロジェクトを作成し、それに依存関係を設定します。 このチュートリアルで説明されているすべてのプロジェクトにspring-cloud-starter-parentをインポートしていることに注意する必要があります。
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-parent
Greenwich.RELEASE
pom
import
注:最新のSpring Cloudリリースはthe Spring’s Projects documentationで確認できます。
次に、メインのアプリケーションクラスを作成します。
@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
Here we’re configuring an application port – 8761 is the default one for Eureka servers.アプリケーションはサーバーとして機能する必要があるため、組み込みのEureka Clientに「itself」に登録しないように指示しています。
次に、ブラウザでhttp://localhost:8761を指定して、Eurekaダッシュボードを表示します。ここで、後で登録されたインスタンスを検査します。
現時点では、ステータスインジケータやヘルスインジケータなどの基本的なインジケータが表示されます。
3. ユーレカクライアント
@SpringBootApplicationを検出に対応させるには、classpath.にいくつかのSpring Discovery Client(たとえば、spring-cloud-starter-netflix-eureka-client)を含める必要があります。
次に、@Configurationに@EnableDiscoveryClientまたは@EnableEurekaClient –のいずれかで注釈を付ける必要があります。spring-cloud-starter-netflix-eureka-clientがクラスパスに依存している場合、この注釈はオプションであることに注意してください。
後者は、Spring Bootにサービス検出にSpring NetflixEurekaを明示的に使用するように指示します。 クライアントアプリケーションをサンプルライフで満たすために、spring-boot-starter-webパッケージをpom.xmlに含め、RESTコントローラーを実装します。
ただし、最初に依存関係を追加します。 繰り返しになりますが、spring-cloud-starter-parent dependencyに任せて、アーティファクトのバージョンを把握することができます。
org.springframework.cloud
spring-cloud-starter-netflix-eureka-starter
org.springframework.boot
spring-boot-starter-web
ここで、メインアプリケーションクラスを実装します。
@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 Clientをセットアップすることにしたとき、この種のサービスは後で簡単にスケーラブルにする必要があることを念頭に置いていました。
次に、クライアントを実行し、ブラウザでhttp://localhost:8761を再度指定して、Eurekaダッシュボードでその登録ステータスを確認します。 ダッシュボードを使用すると、さらに設定を行うことができます。 登録されたクライアントのホームページを管理目的でダッシュボードにリンクします。 ただし、構成オプションはこの記事の範囲外です。
4. 偽のクライアント
3つの依存するマイクロサービスを使用してプロジェクトを完成させるために、Spring Netflix Feign Clientを使用してRESTを消費するWebアプリケーションを実装します。
Feignは、インターフェイスを使用してエンドポイントと通信する検出対応のSpring RestTemplateと考えてください。 このインターフェイスは実行時に自動的に実装され、service-urlsの代わりにservice-namesを使用します。
Feignがないと、EurekaClientのインスタンスをコントローラーに自動配線する必要があります。このコントローラーを使用して、service-nameによるサービス情報をApplicationオブジェクトとして受け取ることができます。
このApplicationを使用してこのサービスのすべてのインスタンスのリストを取得し、適切なインスタンスを選択し、このInstanceInfoを使用してホスト名とポートを取得します。 これにより、任意のhttp clientで標準のリクエストを実行できます。
例えば:
@Autowired
private EurekaClient eurekaClient;
public void doRequest() {
Application application =
eurekaClient.getApplication("spring-cloud-eureka-client");
InstanceInfo instanceInfo = application.getInstances().get(0);
String hostname = instanceInfo.getHostName();
int port = instanceInfo.getPort();
// ...
}
RestTemplateを使用して、Eurekaクライアントサービスに名前でアクセスすることもできますが、このトピックはこの記述を超えています。
Feign Clientプロジェクトを設定するために、次の4つの依存関係をそのpom.xmlに追加します。
org.springframework.cloud
spring-cloud-starter-feign
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
Feign Clientはspring-cloud-starter-feignパッケージにあります。 これを有効にするには、@Configurationに@EnableFeignClientsの注釈を付ける必要があります。 これを使用するには、インターフェイスに@FeignClient(“service-name”)の注釈を付け、コントローラーに自動配線します。
このようなFeignClientsを作成する良い方法は、@RequestMappingアノテーション付きメソッドを使用してインターフェイスを作成し、それらを別のモジュールに配置することです。 これにより、サーバーとクライアント間で共有できます。 サーバー側では、それらを@Controllerとして実装でき、クライアント側では、それらを拡張して@FeignClientとして注釈を付けることができます。
さらに、spring-cloud-starter-eureka packageをプロジェクトに含め、メインアプリケーションクラスに@EnableEurekaClientで注釈を付けることで有効にする必要があります。
spring-boot-starter-webとspring-boot-starter-thymeleafの依存関係は、present a viewに使用され、RESTサービスからフェッチされたデータが含まれます。
これがFeign Clientインターフェースになります:
@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テンプレートになります。
Greeting Page
少なくとも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レジストリをフェッチしようとします。
今when we start up the Eureka server, we don’t want to register the inbuilt client to configure itself with the server。
サーバーの起動中に上記のプロパティをtrueとしてマークすると(または、デフォルトではtrueとして構成しない場合)、組み込みクライアントは自身をEurekaに登録しようとします。サーバーであり、まだ利用できないレジストリをフェッチしようとします。 その結果、TransportExceptionが得られます。
したがって、Eurekaサーバーアプリケーションでこれらのプロパティをtrueとして構成しないでください。 application.ymlに入力する必要がある正しい設定を以下に示します。
eureka:
client:
registerWithEureka: false
fetchRegistry: false
6. 結論
これまで見てきたように、Spring Netflix Eureka Serverを使用してサービスレジストリを実装し、それにいくつかのEureka Clientsを登録できるようになりました。
手順3のEureka Clientはランダムに選択されたポートでリッスンするため、レジストリからの情報がないとその場所を認識できません。 Feign Clientとレジストリを使用すると、場所が変更された場合でも、RESTサービスを見つけて利用できます。
最後に、マイクロサービスアーキテクチャでサービスディスカバリを使用する全体像を把握しました。
いつものように、ソースon GitHub,には、プロジェクトからコンテナを作成するためにdocker-composeとともに使用するためのDocker関連ファイルのセットも含まれています。