春の雲(2):Webサービス・クライアントのリボン

ユーレカで登録されているユーレカからのサービスのリストを取得する方法をどのように上記のサービス登録を実現するだけでなく、します。だから、どのようにサービス呼び出しを行うために、サービスの登録リストを取得しますか?簡単な実装では、サービスインスタンスであるそのホスト名(またはIP)によって呼び出されるサービスの例のリストから選択することができ、ポート、およびパスAPIは、httpクライアント経由で呼び出しを完了するために、完全なURLにスプライス。しかし、これらの機能を達成するために、クライアントコンポーネントの生産環境は、順序要素に、サービスコールのパフォーマンス、高可用性、およびその他のは、一般的にロード・バランシングに関し、フェイルオーバー、障害の再試行の成果なので、導入も不可欠マイクロサービスアーキテクチャとなっています要素。春の雲は、リボンと装うの間でサービスコールを介して達成することができます。

書かれた記事や例のこのシリーズは春クラウドホクストンの最新バージョンに基づいています。

リボン

リボンは、負荷分散のWebクライアントです。負荷分散の私たちの一般的な理解は、nginxのように、サーバ側で実装(これは相対的なバックエンドサービスならば、負荷分散クライアントとしてnginxのを達成することも可能である、相対的である)、およびリボンの顧客れます達成するためのロードバランシングを終了します。

リボンコア概念は、クライアント(という名前のクライアント)と命名され、春の雲はRibbonClientConfigurationによってILoadBalancer、RestClient、ServerListFilterなどビーンを作成するには、この文脈では、それぞれの名前のクライアントのためのサブアプリケーションのコンテキスト(ApplicationContextの)を作成します。

春の雲はNetflixが提供するデフォルトのリボン豆と指示

豆の種類 デフォルトの実装クラス 説明
IClientConfig DefaultClientConfigImpl 負荷を達成するためにリボンクライアント構成、豆およびクライアント接続タイムアウトの負荷の実装、通信タイムアウトの設定
iRule ZoneAvoidanceRule ベースのゾーンとルールサーバをフィルタリング達成するために利用可能
IPing DummyPing サーバーの生存率は、デフォルトでは常にtrueを返すかどうかを判断達成
サーバリスト ConfigurationBasedServerList デフォルトの設定に基づいて、達成するために、サーバのリストを取得します。
ServerListFilter ZonePreferenceServerListFilter 実現Serverのフィルタは、デフォルトのサーバーリストは、同じゾーン内のクライアントでフィルタリングします
ILoadBalancer ZoneAwareLoadBalancer 最高負荷のデフォルト負荷領域の要請で実現するために、ロード・バランシング、ゾーンの残りの部分から、ゾーンを除外し、与えられたルールからサーバを選択]を選択
ServerListUpdater PollingServerListUpdater 動的サーバリストアップデータ

 

春の雲の構成は、次のような、私たちはデフォルトの実装を調整したり、カバーするために宣言することで、クライアントをカスタマイズすることができます

@Configuration 
@RibbonClient(名= "カスタム"、構成= CustomConfiguration.class)
パブリック クラス TestConfiguration {

}

したがって、RibbonClientConfigurationによってクライアントと一緒に組成物がアセンブリCustomConfigurationを定義し、前者を覆うアセンブリ意志CustomConfiguration。

注CustomConfigurationは@Configurationは、クラスを変更する必要があり、かつ主走査@ComponentScanアプリケーションコンテキストことができない、それ以外は全て@RibbonClientsによって共有されます

あなたはすべてのリボンクライアントのデフォルトの設定をカスタマイズしたい場合は、@RibbonClientsコメントを使用することができます

@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
public class RibbonClientDefaultConfigurationTestsConfig {

}

 

也可以通过配置属性来定制Ribbon Client,支持的配置属性

<clientName>.ribbon.NFLoadBalancerClassName: ILoadBalancer接口实现类
<clientName>.ribbon.NFLoadBalancerRuleClassName: IRule接口实现类
<clientName>.ribbon.NFLoadBalancerPingClassName: IPing接口实现类
<clientName>.ribbon.NIWSServerListClassName: ServerList接口实现类
<clientName>.ribbon.NIWSServerListFilterClassName: ServerListFilter接口实现类

 

比如对于一个服务名称为users的配置

users:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

 

配置属性的优先级 > configuration指定配置类的优先级 > 默认RibbonClientConfiguration的优先级, 即同样的实现,前者覆盖后者。

当Eureka与Ribbon同时存在时,ribbonServerList会被 DiscoveryEnabledNIWSServerList覆盖,从Eureka来获取server list,同时 NIWSDiscoveryPing也会替换IPing接口,代理Eureka来确定服务器是否处于运行状态。

Ribbon的超时与重试配置

  • <clientName>.ribbon.ConnectTimeout: 请求连接超时时间,默认2000
  • <clientName>.ribbon.ReadTimeout: 请求处理超时时间,默认5000
  • <clientName>.ribbon.MaxAutoRetries: 在同一台服务器上的重试次数,排除第一次调用,默认0
  • <clientName>.ribbon.MaxAutoRetriesNextServer: 切换服务器的重试次数,默认1
  • <clientName>.ribbon.OkToRetryOnAllOperations: 对所有请求都进行重试,默认false

当项目中添加了Spring Retry的依赖,则会启用重试机制。当请求失败时,会再尝试访问当前服务器(次数由MaxAutoRetries配置),如果不行,就换一个服务器进行访问,如果还是不行,再换服务器访问(更换次数由MaxAutoRetriesNextServer配置),如果还是不行,则返回请求失败。

Ribbon的负载均衡策略

前文提到Ribbon的负载均衡默认实现为ZoneAwareLoadBalancer,那么Ribbon提供的负载均衡策略还有哪些? 罗列如下

  • BestAvailableRule: 排除掉断路器打开的服务器,选取并发请求最小的服务器
  • AvailabilityFilteringRule: 过滤掉断路器打开或活跃连接数超过限制(通过<clientName>.<nameSpace>.ActiveConnectionsLimit配置,默认为Integer.MAX_VALUE)的服务器
  • WeightedResponseTimeRule: 根据平均响应时间来动态为服务器赋予权值,实现基于权重的轮询
  • RetryRule: 对选择负载均衡策略添加重试机制
  • RoundRobinRule: 简单轮询
  • RandomRule: 随机轮询
  • ZoneAvoidanceRule: 结合区域与可用性来选择服务器,也是默认实现

可通过如下配置修改Ribbon的负载均衡策略

client-name:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

 

案例演示

本文案例演示基于上文搭建的springcloud-eureka 与 springcloud-eureka-client 两个示例项目 (源码),依次启动两个项目,然后将springcloud-eureka-client项目的端口 server.port改为8081,新开一个springboot运行配置,如图

Eureka客户端2

以8081端口再起一个springcloud-eureka-client的服务实例。这是查看Eureka页面 http://localhost:8761/, 可以看到hello-service服务注册了两个实例

hello服务注册

新建springcloud-ribbon项目 (源码

pom.xml中引入依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

编写测试接口, LoadBalanceClient 是Ribbon的API

@RestController
public class RibbonTestController {

@Autowired
private LoadBalancerClient loadBalancer;

@GetMapping("ribbon")
public String testRibbon(){
ServiceInstance instance = loadBalancer.choose("hello-service");
return String.format("http://%s:%s", instance.getHost(),
instance.getPort());
}
}

 

启动springcloud-ribbon, 调用测试接口 http://localhost:8082/ribbon, 可以看到返回结果交替显示 http://CN-201911061714:8080, http://CN-201911061714:8081 (CN-201911061714是我电脑的hostname,你的可能不一样),可见Ribbon实现了客户端的负载均衡。

一些知识点

  1. Ribbon如果对所有请求进行重试,则需要保证接口的幂等性(多次调用产生的结果是一致的)

  2. 每一个命名的Ribbon客户端都有一个相应的由Spring cloud维护的子应用上下文,默认是lazy load的(第一次请求客户端时才load),可以通过如下配置更改为启动立即加载

    ribbon:
    eager-load:
    enabled: true
    clients: client1, client2, client3
  3. client.ribbon.* 针对单个客户端进行配置,针对所有客户端默认配置,则使用ribbon.*

  4. 当结合断路器使用时, 断路器的超时时间要大于Ribbon的超时时间,不然不会触发重试(还没重试就触发断路器打开了)

  5. 除了Ribbon,能做负载均衡访问的Web客户端还有@LoadBalance 注解的RestTemplate, 与Feign

本文示例代码

 

 


认真生活,快乐分享
欢迎关注微信公众号:空山新雨的技术空间
微信公众号

おすすめ

転載: www.cnblogs.com/spec-dog/p/12196237.html