SpringCloud(5)-リボン
リボンの紹介
- Spring Cloud Ribbonは、Netflix Ribbonに基づくクライアントロードバランシングツールのセットです。
- 簡単に言うと、リボンはNetflixによってリリースされたオープンソースプロジェクトであり、その主な機能は、クライアントにソフトウェアロードバランシングアルゴリズムを提供し、Netflixの中間層サービスを接続することです。リボンのクライアントコンポーネントは、接続タイムアウト、再試行などの一連の完全な構成項目を提供します。簡単に言うと、LoadBalancer(LB:負荷分散と略される)の背後にあるすべてのマシンが構成ファイルにリストされています。リボンは、特定のルール(単純なポーリング、ランダム接続など)に基づいてこれらのマシンを自動的に接続するのに役立ちます。また、リボンを使用してカスタムロードバランシングアルゴリズムを実装するのも非常に簡単です。
ロードバランス
-
LB、またはロードバランスは、マイクロサービスまたは分散クラスターでよく使用されるアプリケーションです。
-
負荷分散とは、システムのHA(高可用性)を実現するために、ユーザーのリクエストが複数のサービスに均等に分散されることを意味します。
-
一般的な負荷分散ソフトウェアには、Nginx、Lvsなどがあります。
-
DubboとSpringCloudはどちらもロードバランシングを提供しており、SpringCloudのロードバランシングアルゴリズムはカスタマイズできます。
-
負荷分散の簡単な分類:
- 集中型LB
つまり、Nginx(リバースプロキシサーバー)などのサービスのコンシューマーとプロバイダー間で独立したLB機能を使用します。これは、特定の戦略を通じてサービスプロバイダーにアクセス要求を転送する役割を果たします。
- プログレッシブLB
LBロジックをコンシューマーに統合すると、コンシューマーはサービス登録センターから利用可能なアドレスを認識し、これらのアドレスから適切なサーバーを選択します。リボンはプロセスLBに属します。これは単なるクラスライブラリであり、コンシューマープロセスに統合されています。コンシューマーはサービスプロバイダーのアドレスを取得します。
リボンを統合する
- リボンの依存関係とEurekaの依存関係を元のクライアントのspringcloud-consumer-dept-80プロジェクトのpomファイルに追加します
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- application.ymlでEurekaを構成する
eureka:
instance:
hostname: localhost #eureka服务端实例名称
client:
register-with-eureka: false #表示是否向eureka注册自己
fetch-registry: false #如果为false表示自己为注册中心
service-url: #监控页面
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
- メインスタートアップクラスでEurekaClientを起動します
@EnableEurekaClient
@SpringBootApplication
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
- 元のBeanConfigを変更する
//配置负载均衡实现RestTemplate
@Bean
@LoadBalanced //Ribbon
public RestTemplate restTemplate(){
return new RestTemplate();
}
- DeptConsumerControllerの元のREST_PATH_PREFIXをアプリケーション名に変更し、サービス名に基づいてアクセスします。クライアントは、サービスプロバイダーのIPアドレスとポート番号を気にする必要はありません。(元々:プライベート静的最終文字列REST_PATH_PREFIX = " http:// localhost:8001 ")
private static final String REST_PATH_PREFIX="http://springcloud-provider-dept";
- プロジェクトを開始し、http:// localhost / consumer / dept / allにアクセスしてテストします。
負荷分散を実現するリボン
-
2つの新しいデータベースsc02、sc03を作成します。データは、db_sourceを除いてsc01と同じです。
-
2つの新しいMavenプロジェクトspringcloud-provider-dept-8002およびspringcloud-provider-dept-8003を作成します。springcloud-provider-dept-8001プロジェクトのすべてをコピーします。
-
springcloud-provider-dept-8002、springcloud-provider-dept-8003 application.ymlのポート番号、接続されているデータベースの名前、およびEurekaのデフォルトの説明情報を変更します
-
3つのサービスプロバイダーのアプリケーション名が同じであることを確認します。
spring:
application:
name: springcloud-provider-dept
- マッパーのdeptテーブルを変更して、対応するデータベースを照会することを忘れないでください。
- 対応する起動クラスを記述します。
- プロジェクトを開始し、http:// localhost:7001 /:にアクセスします。
http:// localhost / consumer / dept / allにアクセスし、ページを何度も更新して、さまざまなデータベースが照会されることを確認します(デフォルトのアルゴリズムは単純なポーリングです)。
カスタム負荷分散アルゴリズム
- サービスコンシューマーspringcloud-consumer-dept-80を選択し、com.yinrzパッケージの下に新しいパッケージmyruleを作成し、カスタム負荷分散アルゴリズムクラスMyRuleを記述します。
//自定义负载均衡算法:一个服务连续访问5次后,换下一个服务
public class MyRule extends AbstractLoadBalancerRule {
public MyRule(){
}
private int total=0;
private int current=0;
@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers(); //活着的服务
List<Server> allList = lb.getAllServers(); //所有服务
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//========================核心算法开始==============================
System.out.println(111);
if(total<=5){
server = upList.get(current);
total++;
}else {
total=0;
current++;
if (current>=upList.size()){
current=0;
}
server = upList.get(current);
}
//========================核心算法结束==============================
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
@Override
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
- myruleパッケージの下に構成クラスMyRuleConfigを記述します。
@Configuration
public class MyRuleConfig {
@Bean
public IRule myRule(){
return new MyRule();
}
}
- メインのスタートアップクラスにアノテーション@RibbonClientを追加します。
@EnableEurekaClient
@SpringBootApplication
@RibbonClient(name = "springcloud-provider-dept",configuration = MyRuleConfig.class)//在微服务启动的时候就能加载我们自定义的Ribbon类
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
- 3つのサービスプロバイダー、Eurekaサーバー、サービスユーザープロジェクトを実行し、http:// localhost / consumer / dept / allにアクセスしてテストします。