著者のプラットフォーム:
| CSDN:blog.csdn.net/qq_41153943
| ナゲッツ: juejin.cn/user/651387…
| 志湖: www.zhihu.com/people/1024…
| GitHub: github.com/JiangXia-10…
この記事は合計 4529 ワードあり、読むのにかかる時間は 12 分です。
序文
前回の記事では、マイクロサービスとは何か、いくつかの共通サービス レジストリ コンポーネント、マイクロサービス間の通信方法など、マイクロサービスに関連する内容を紹介しました。
マイクロサービス アーキテクチャにおけるもう 1 つの一般的なシナリオは、サービスの負荷分散です。今日は Spring Cloud - リボンが提供する負荷分散コンポーネントを一緒に学びましょう。
リボンとは
Spring Cloud リボンは、http および tcp に基づいたクライアント負荷分散ツールです。netflix リボンに基づいて実装されています。Spring Cloud カプセル化を通じて、サービス指向の Resttemplate リクエストをクライアント負荷分散サービス呼び出しに自動的に変換できます。
したがって、リボンは SpringCloud によって提供されるクライアント負荷分散コンポーネントのセットであり、HTTP および TCP クライアントの動作の制御に役立つ、タイムアウト、再試行などの一連の包括的な構成を提供します。サービスによって提供されるすべてのマシン インスタンスはロード バランサーを通じて取得され、リボンは特定のルール (デフォルトはポーリング メカニズム) に基づいてこれらのサービスを自動的に呼び出します。リボンは独自の負荷分散アルゴリズムを実装することもできます。
タイトル リボンの負荷分散戦略
リボン負荷分散に基づいて、Netflix はデフォルトで次の 7 つの負荷分散戦略を提供します。
1. RoundRobinRule (ポーリング戦略)
ポーリング戦略はリボンのデフォルトの戦略であり、すべてのサービス インスタンスに順番にアクセスします。たとえば、合計 3 つのサービスがあり、最初にサービス 1 が呼び出され、2 回目にサービス 2 が呼び出され、3 回目にサービス 3 が呼び出されます。
2. WeightedResponseTimeRule (重み戦略)
重み付け戦略とは、各サービスプロバイダーの応答時間に応じて重み付けをするもので、応答時間が長いほど重み付けが小さくなり、選択される可能性が低くなります。その実装原理は、ポーリング戦略の使用を開始してタイマーを開始し、すべてのサービス プロバイダーの平均応答時間を時々収集し、各サービス プロバイダーに重みを付け、より高い重みが選択されるようにすることです。確率も高くなります。もっと大きい。
3. RetryRule (リトライ戦略)
再試行戦略とは、ポーリング戦略に従ってサービスを取得することを指します。取得されたサービス インスタンスが null または無効な場合は、指定された時間内にサービスを取得するために再試行が続行されます。指定された時間を過ぎてもサービスが取得されない場合は、インスタンスが取得されます。 null を返します。
4. RandomRule (ランダム戦略)
ランダム戦略は比較的単純で、サービス プロバイダーのリストからサービス インスタンスをランダムに選択することを意味します。
5. BestAvailableRule (最小接続数戦略)
最小接続数戦略は、最小同時実行数戦略とも呼ばれ、サービス プロバイダーのリストを調べて、接続数が最小のサービス インスタンスを選択することを指します。最小接続数が同じ場合は、ポーリング戦略が選択のために呼び出されます。
6. ZoneAvoidanceRule (ゾーン依存ポリシー)
リージョン依存の戦略は、サービスが配置されているリージョンのパフォーマンスとサービスの可用性に基づいてサービス インスタンスを選択します。リージョンのない環境では、この戦略はポーリング戦略と似ています。
7. AvailabilityFilteringRule (利用可能な機密性ポリシー)
利用可能な機密性戦略は、まず異常なサービス インスタンスをフィルターで除外し、次に接続数が少ないサービス インスタンスを選択することです。
リボンでは、RoundRobinRule の設定など、次のコマンドを使用して負荷分散戦略を指定できます。
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
他のポリシーを設定し、特定のポリシー名を変更します。
さらに、負荷分散戦略をカスタマイズすることもできます。負荷分散戦略をカスタマイズするには、com.netflix.loadbalancer.AbstractLoadBalancerRule 抽象クラスを継承する必要があります。
戦闘
プロジェクトが spring-cloud-starter-consul-discovery 依存関係をインポートすると、プロジェクトにリボンの依存関係が含まれるため、リボンの依存関係を追加でインポートする必要はありません。このプロジェクトは前のプロジェクトに基づいています。Consul の記事の SpringCloud シリーズ: Service Registry Components - プロジェクトを参照してください。
resttemplate+ribbon コンポーネントを使用して負荷分散を実現するには、主に 3 つの方法があります。
1. DiscoveryClient オブジェクトを使用する
DiscoveryClient は、サービス レジストリから情報を取得するために使用できるサービス検出クライアント オブジェクトです。
@Autowired
private DiscoveryClient discoveryClient;
//创建一个RestTemplate对象
RestTemplate restTemplate = new RestTemplate();
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("orders");
serviceInstances.forEach(serviceInstance -> {
logger.info("服务主机:{};服务地址:{};服务端口:{}",serviceInstance.getHost(),serviceInstance.getUri(),serviceInstance.getPort());
});
String result = restTemplate.getForObject(serviceInstances.get(0).getUri()+"/order/order",String.class);
DiscoveryClient の getInstances メソッドを使用して、サービス ID に応じてサービス レジストリから対応するサービス リストを取得しますが、ここでは負荷分散が行われていないことがわかり、依然として自分で負荷分散を実現する必要があり、サービスを接続する必要があります。
2. LoadBalancerClient オブジェクト
LoadBalancerClient オブジェクトは負荷分散クライアント オブジェクトです。また、サービス レジストリに移動してサービス ID に従って対応するサービス リストを取得し、デフォルトの負荷分散戦略に従ってサービス リスト内のマシンを選択してそれを返します。ここで返されるのは service であり、DiscoveryClient はサービスのリストを返します。
ServiceInstance serviceInstance = loadBalancerClient.choose("orders");
logger.info("服务主机:{};服务地址:{};服务端口:{}",serviceInstance.getHost(),serviceInstance.getUri(),serviceInstance.getPort());
String result = restTemplate.getForObject(serviceInstance.getUri()+"/order/order",String.class);
LoadBalancerClient を使用する場合、サービス ID に従って負荷分散されたマシンを取得し、resttemplate を通じてサービスを呼び出す必要があることがわかりますが、これも複雑で面倒です。
3. @LoadBalanced アノテーションを使用する
@LoadBalanced アノテーションは、クラウド パッケージのアノテーションです。このアノテーションは、何かに負荷分散機能を持たせることを目的としています。このアノテーションは、主にメソッドで使用されます。
たとえば、この RestTemplate に、リクエスト時にクライアントの負荷分散機能を持たせるようにします。次のように構成クラスに記述できます。
@Configuration
public class MyConfig {
@Bean
@LoadBalanced //使其具有负载均衡属性
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
次に、負荷分散が必要な場合は、サービス名 + リクエスト パスを使用します。
String result = restTemplate.getForObject("http://orders/order/order",String.class);
プロジェクトを開始する場合は、次のように入力します。
http://localhost:8083/user/user
そして、更新とリクエストの作成を続けると、デフォルトのポーリング負荷分散戦略に従って、順番にポート 8084 と 9999 でリクエストを要求します。 上記のコードを通じて、リボンがクライアントの負荷分散とその負荷分散であることがわかります
。サービス ID は、呼び出し側サービスに基づいています。サービス ID は、サービス登録センターにアクセスして、サービス ID に対応するサービス リストを取得し、サービス リストをローカル キャッシュにプルし、既存のリスト内の利用可能なノードを選択して、次の条件に従ってローカルにサービスを提供します。負荷分散メカニズム。
リボンはクライアント側の負荷分散の一種で、リボンを使用した負荷分散は大きく次の手順に分かれます。
1. まずリクエストをインターセプトし、リクエスト内の URL アドレスを通じてサービス名をインターセプトします。
2. LoadBalancerClient を通じて ILoadBalancer を取得します。
3. サービス ID に基づいて、Eureka や Consul などのサービス登録センターでサービス リストを取得します。
4. IRule 負荷分散戦略を通じて特定のサービスを選択します。
5. ILoadBalancer は、IPing および定期的な更新メカニズムを通じてサービス リストを維持します。
6. URL を再構築し、最後に HttpURLConnection を呼び出してリクエストを開始します。
要約する
以上がspringcloudでresttemplate+ribbonを使って負荷分散を実現する内容です。リボンはクライアントの負荷分散であり、サービス登録センターにアクセスして、呼び出し側サービスのサービス ID に応じて対応するサービス ID のサービス リストを取得し、そのサービス リストをローカル キャッシュにプルすることで負荷分散を実装します。一部のリストでは、サービスを提供するために利用可能なノードを選択します。
質問や間違っている箇所がありましたら、ご指摘、交換、議論大歓迎です!
記事プロジェクトのソース コードは、https://github.com/JiangXia-1024/SpringCloudProjectにあります。