単一のサービス名でサービスの複数インスタンスが実行されている場合、サービス利用者はリクエストを各インスタンスに分散させる必要があります。Enterprise Distributed Application Service (EDAS) 上の Spring Cloud アプリケーションは、クライアントサイドの負荷分散に Ribbon を使用します。Ribbon は RestTemplate と Feign を介して行われるサービス呼び出しをインターセプトし、Nacos に登録されているインスタンスにリクエストを分散します。
仕組み
Nacos はサービスレジストリとして機能します。サービス利用者がサービスプロバイダーを名前で (例:http://service-provider/query) 呼び出すと、Ribbon はその名前を登録済みインスタンスのリストに解決し、それらのインスタンスにリクエストを分散します。
Nacos は、NacosServerList を通じて標準の com.netflix.loadbalancer.ServerList インターフェイスを実装します。他のサービス検出ツールも同じインターフェイスを実装しています:
| サービス検出ツール | ServerList の実装 |
|---|---|
| Nacos | NacosServerList |
| Eureka | DomainExtractingServerList |
| Consul | ConsulServerList |
| ZooKeeper | ZookeeperServerList |
すべての実装がこのインターフェイスを共有しているため、Eureka、Consul、または ZooKeeper から Spring Cloud Alibaba に切り替えても、RestTemplate、Feign、または非推奨の AsyncRestTemplate のコードを変更する必要はありません。
前提条件
開始する前に、次のものが揃っていることを確認してください:
Nacos をサービスレジストリとして使用し、EDAS にデプロイされた Spring Cloud アプリケーション
少なくとも 1 つのサービスプロバイダーと 1 つのサービス利用者
(任意) EDAS と Hystrix の互換性を確保するために、ご利用のコンシューマーに Hystrix の依存関係を追加します。これにより、フォールバック属性がサポートされます。この機能は Sentinel によっても実装可能です。
サンプルアプリケーション
以下のデモプロジェクトをダウンロードして、手順に従ってください:
RestTemplate への負荷分散の追加
RestTemplate は、RESTful サービス向けの Spring HTTP クライアントです。RestTemplate の Bean に @LoadBalanced アノテーションを追加して、クライアントサイドの負荷分散を有効にします。
public class MyApp {
// @LoadBalanced アノテーションは、この RestTemplate に LoadBalancerInterceptor を追加します。
// LoadBalancerInterceptor は RibbonLoadBalancerClient を使用して、Nacos に登録されているサービスインスタンスにリクエストを分散します。
@Autowired
private RestTemplate restTemplate;
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// ホスト名の代わりにサービス名 ("service-provider") を使用します。
// Ribbon はそれを解決し、利用可能なインスタンスを返します。
public void doSomething() {
Foo foo = restTemplate.getForObject("http://service-provider/query", Foo.class);
doWithFoo(foo);
}
...
}@Beanメソッドの@LoadBalancedは、RibbonLoadBalancerClientを介してリクエストをルーティングするLoadBalancerInterceptorを登録します。URL のホスト名としてサービス名 (例:
service-provider) を使用します。Ribbon は、それを利用可能なインスタンスの IP アドレスとポートに置き換えます。
Feign への負荷分散の追加
Feign は、RESTful API 呼び出しを簡素化する宣言的な HTTP クライアントです。Feign クライアントが Nacos に登録されたサービス名を参照すると、負荷分散は自動的に機能します。
手順1: Feign の有効化
Spring Boot アプリケーションクラスに
@EnableFeignClientsを追加します:@SpringBootApplication @EnableFeignClients public class MyApplication { ... }手順2: Feign クライアントインターフェイスの定義
@FeignClientでアノテーションが付けられたインターフェイスを作成します。nameパラメーターをターゲットのサービス名に設定します:@FeignClient(name = "service-provider") public interface EchoService { @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) String echo(@PathVariable("str") String str); }手順3: Feign クライアントのインジェクションと呼び出し
インターフェイスをインジェクションし、そのメソッドを呼び出します。各呼び出しは、
service-providerインスタンスのいずれかへの HTTP リクエストをトリガーします:public class MyService { @Autowired private EchoService echoService; public void doSomething() { // GET http://service-provider/echo/test と同等です // Ribbon は Nacos からインスタンスを選択し、リクエストをルーティングします。 echoService.echo("test"); } ... }
負荷分散の検証
service-consumer サービスと複数の service-provider サービスが開始された後、service-consumer によって提供される URL にアクセスして、負荷分散が実装されているかどうかを確認します。
RestTemplate
/echo-rest/rest-testに複数回アクセスし、リクエストが異なるインスタンスに転送されるかどうかを確認します。Feign
/echo-feign/feign-testに複数回アクセスし、リクエストが異なるインスタンスに転送されるかどうかを確認します。