ribbon 是一个基于 http 和 tcp 的客户端负载均衡器, 用于微服务间的调用及 api 网关请求转发, 默认采用轮询的方式, 动态感知服务节点的增减
服务消费方
1.jar包导入
spring-cloud-starter-netflix-ribbon
2.配置代码
自定义一个标记注解
public @interface AvoidScan {}
配置启动类
@RibbonClients(value = {
@RibbonClient(name = "micro-order", configuration = OrderServiceRibbonConfiguration.class),
@RibbonClient(name = "micro-good", configuration = GoodServiceRibbonConfiguration.class)
})
单个源服务的 ribbon 配置, 需要从扫描范围排除, 否则扫描到一个就变成全局, 多个就启动报错
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {AvoidScan.class})})
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
针对单个源服务的 ribbon 配置
@Configuration
@AvoidScan
public class OrderServiceRibbonConfiguration {
@Autowired
IClientConfig config;
@Bean
public IRule ribbonRule(IClientConfig config) {
return new RoundRobinRule();
}
}
3.配置文件 -- 配置文件的优先级高于注解
//# 关闭 ribbon 访问注册中心 Eureka 发现服务,但是服务依旧会注册
ribbon.eureka.enabled=true
spring.cloud.loadbalancer.retry.enabled=true
//# 对某个源服务的 ribbon 配置
//# serviceName.ribbon.*
//# 指定调用的节点 localhost:8001 localhost:8002 localhost:8003
//# micro-order.ribbon.listOfServers=localhost:8001,localhost:8002,localhost:8003
//# 单位ms ,请求连接超时时间
//# micro-order.ribbon.ConnectTimeout=1000
//# 单位ms ,请求处理超时时间
//# micro-order.ribbon.ReadTimeout=2000
//# micro-order.ribbon.OkToRetryOnAllOperations=true
//# 对当前实例的重试次数 当 Eureka 中可以找到服务,但是服务连不上时将会重试
//# micro-order.ribbon.MaxAutoRetries=2
//# 切换实例的重试次数,不包括第一个服务
//# micro-order.ribbon.MaxAutoRetriesNextServer=2
//# micro-order.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
//# micro-order.ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl
负载均衡策略
RandomRule
随机策略,随机选择 server
RoundRobinRule
线性轮询,按顺序循环选择 server
RetryRule
重试轮询,在一个配置时间段内,选择 server 不成功,则一直尝试选择一个可用的 server
BestAvailableRule
最低并发策略,过滤掉断路器打开的 server, 再选择并发连接最低的 server
AvailabilityFilteringRule
可用过滤策略,过滤掉一直连接失败并被标记为 circuit tripped 的 server, 过滤掉那些高并发连接的 server (active connections 超过配置的阈值)
ResponseTimeWeightedRule
响应时间加权策略,根据 server 的响应时间分配权重,响应时间越短,权重越高,被选择到的概率就越高
ZoneAvoidanceRule
区域权衡策略,跨区域选择性能好的 server
IClientConfig -- 管理配置
DefaultClientConfigImpl -- 定义默认配置
IPing -- 检查可用性
DummyPing -- 写死返回true
ServerList -- 获取服务列表
ConfigurationBasedServerList
ServerListFilter -- 获取特定期望服务列表
ServerListUpdater -- 动态更新服务列表,支撑 DynamicServerListLoadBalancer
PollingServerListUpdater
LoadBalancerAutoConfiguration
通过 RestTemplateCustomizer 为 RestTemplate 增加 LoadBalancerInterceptor
LoadBalancerInterceptor 拦截 RestTemplate 请求, 通过 LoadBalancerClient 处理请求,
LoadBalancerClient 通过 ILoadBalancer 做负载均衡,ILoadBalancer 通过 IRule 选择 Server,
把请求 url 里的 serviceName 替换为 host:port
问题:
1.第一次调用服务报错,再调又正常了
Ribbon 里 LoadBalancerClient 默认懒加载,所以第一次调用需要初始化会慢一点,如果超时时间又设置的比较短, 就会报错
//# 配置 Ribbon 饥饿加载
ribbon.eager-load.enabled=true
//# 指定需要饥饿加载的服务名,多个用逗号分隔
ribbon.eager-load.clients=micro-order