介绍
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具, 它基于Netflix Ribbon实现. 通过Spring Cloud 的封装, 可以让我们轻松的将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用. Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署, 但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中.因为微服务的调用, API网关请求的转发等内容, 实际都是通过Ribbon实现的.
客户端负载均衡中,所有客户端节点都维护着自己要访问的服务清单,而这些服务清单来自于服务注册中心,比如Eureka服务端. 使用心跳去维护服务端清单的健康性(需要于服务注册中心配合).
在Sring Cloud实现的服务治理框架中, 默认会创建针对各个服务治理框架的Ribbon自动化整合配置,比如Eureka中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration
, Consul中的 org.springframework.cloud.consul.discovery.RibbonConsulAutoConfiguration
. 在实际使用中可以通过这两个类的实现找到配置详情.
通过Spring Cloud Ribbon的封装, 在微服务架构中使用客户端负载均衡调用非常简单
-
服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心
-
服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用
// 使用@LoadBalanced注解修饰
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@RestController
public class ConsumerController {
@Resource
private RestTemplate restTemplate;
@GetMapping("/ribbon-consumer")
String helloConsumer() {
// 调用
return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
}
}
自动化配置
Spring Cloud中定义的每一个接口都有多种不同的策略实现, 在引入Spring Cloud Ribbon的依赖之后, 就能够自动化构建下面接口的实现
-
IClientConfig: Ribbon的客户端配置, 默认采用
com.netflix.client.config.DefaultClientConfigImpl
实现 -
IRule: Ribbon的负载均衡策略, 默认采用
com.netflix.loadbalancer.ZoneAvoidanceRule
实现,该策略能够在多区域环境下选出最佳区域的实例进行访问. -
IPing: Ribbon的实例检查策略, 默认采用
com.netflix.loadbalancer.NoOpPing
实现,该检查策略是一个特殊实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服务实例都是可用的.
public class NoOpPing implements IPing {
public NoOpPing() {
}
public boolean isAlive(Server server) {
return true;
}
}
-
ServerList
: 服务实例清单的维护机制,默认采用 org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter
实现, 该策略能够优先过滤出与请求方处于同区域的服务实例. -
ILoadBalancer:负载均衡器,默认采用
com.netflix.loadbalancer.ZoneAwareLoadBalancer
实现, 具备区域感知的能力.
上面这些自动化配置内容在没有引入Spring Cloud Eureka等服务治理框架时如此, 在同时引入Eureka和Ribbon依赖时, 自动化配置会有一些不同.
参数配置
Ribbon的参数配置通常有两种方式: 全局配置
和指定客户端配置
- 全局配置只需要使用
ribbon.<key>=<value>
格式进行配置.<key>
代表Ribbon客户端配置的参数名,<value>
代表对于参数的值. 比如全局配置Ribbon创建连接的超时时间:
ribbon.ConnectTimeout=300
全局配置可以作为默认值进行配置, 当指定客户端配置了相应的key
的值时,将覆盖全局配置的内容.
- 指定客户端配置的方式采用
<client>.ribbon.<key>=<value>
的格式配置.<key>
和<value>
的含义同全局配置相同,而<client>
代表客户端的名称.
// 客户端名称
spring.application.name=hello-service
// 客户端配置
hello-service.ribbon.listOfServers=localhost:8001,localhost:8002...
更多key
和value
的定义在com.netflix.client.config.CommonClientConfigKey
类中.
与Eureka结合
当Spring Cloud的应用中同时引入Spring Cloud Eureka和Spring Cloud Ribbon依赖时, 会触发Eureka中实现的对Ribbon的自动化配置.
-
ServerList
的维护机制实现将被com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
的实例所覆盖,该实现会将服务清单列表交给Eureka的服务治理机制来维护. -
IPing
的实现将被com.netflix.niws.loadbalancer.NIWSDiscoveryPing
的实例覆盖.该实例也将实例检查的任务交给了服务治理框架来维护. -
ServerList
接口实现采用Spring Cloud Eureka中封装的org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList
目的时为了让实例维护的策略更加通用, 所以将使用物理元数据进行负载均衡,而不是使用原生的AWS AMI数据.
在与Spring Cloud Eureka结合使用时, 不在需要通过类似hello-service.ribbon.listOfServers
参数指定具体的服务实例清单, Eureka会为我们维护所有的服务实例清单. 指定客户端的配置可以直接使用Eureka的服务名作为<client>
完成个性化配置.
Spring Cloud Ribbon默认实现了区域亲和策略, 所以可以通过Eureka实例的元数据配置来实现区域化的实例配置方案. 比如可以将不同机房的实例配置成不同区域值, 作为跨区域容错机制实现.
eureka.instance.metadataMap.zone=xian
重试机制
CAP
指的是一致性, 可用性, 可靠性.
Spring Cloud Eureka实现的服务治理强调了CAP
原理中的AP
, 而与Zookeeper强调CP
的服务治理框架最大的区别就是Eureka为了实现更高的服务可用性,牺牲了一定的一致性.在极端情况下宁愿接受故障实例也不丢掉健康的实例.Eureka在超过85%的实例丢失心跳时会触发保护机制,注册中心将保留所有节点, 服务之间依然可以进行相互调用
重试能力配置如下:
# 开启重试机制, 默认关闭
spring.cloud.loadbalancer.retry.enabled=true
# 断路器超时时间需大于Ribbon的超时时间, 否则不会触发重试
histrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
# 请求连接的超时时间
hello-service.ribbon.ConnectTimeout=300
# 请求处理的超时时间
hello-service.ribbon.ReadTimeout=1000
# 对所有操作都进行重试
hello-service.ribbon.OkToRetryOnAllOperations=true
# 切换实例的重试次数
hello-service.ribbon.MaxAutoRetriesNextServer=2
# 对当前实例的重试次数
hello-service.ribbon.MaxAutoRetries=1
当访问到故障请求时, 会尝试访问一次当前实例(MaxAutoRetries), 如果不行, 就换一个实例进行访问, 如果还是不行就继续切换实例访问(MaxAutoRetriesNextServer), 如果依然不行就返回失败信息.
本文由 anybbo 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Dec 17,2020