SpringCloud学习笔记-ribbon

我的梦境 提交于 2020-03-08 21:32:48

ribbon

简介

Ribbon是Netflix发布的负载均衡器,它可以帮我们控制HTTP和TCP客户端的行为。只需为Ribbon配置服务提供者地址列表,Ribbon就可基于负载均衡算法计算出要请求的目标服务地址。
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
在这里插入图片描述
github地址

使用

为服务消费者整合ribbon

  • 引用依赖
    spring-cloud-starter-netflix-eureka-client包含了ribbon依赖,如果引入了spring-cloud-starter-netflix-eureka-client,则无需再引入ribbon依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
  • 为restTemplate加上@LoadBalanced注解
    只需加入@LoadBalanced注解即可整合ribbon功能,使restTemplate具有负载均衡的能力
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
  return new RestTemplate();
}

将请求地址改成微服务的虚拟主机名,当Ribbon和Eureka配合使用时,会自动将虚拟主机名映射成微服务的网络地址。
restTemplate.getForObject("http://virtualHostName/test", String.class);
可使用 LoadBalancerClient 的API更加直观地获取当前选择的用户微服务节点。但 loadBalancerClient.chooserestTemplate.getForObject不能写在同一个方法中,两者会有冲突,因为此时代码中restTemplate实际上是一个Ribbon客户端,本身已经包含了“choose”的行为。

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping("invokeMethod")
    public void invokeMethod() {
        String forObject = restTemplate.getForObject("http://eureka-client-producer/userInfo", String.class);
        System.out.println(forObject);
    }

    @GetMapping("logUserInstance")
    public void logUserInstance() {
        ServiceInstance choose = this.loadBalancerClient.choose("eureka-client-producer");
        System.out.println(choose.getServiceId()+"  "+choose.getHost()+"  "+choose.getPort());
    }

}

虚拟主机名不能包含下划线(_),否则ribbon在调用时会报错
Request URI does not contain a valid hostname

  • 默认情况下,虚拟主机名和服务名称一致,也可以使用以下配置单独设置:
eureka:
  instance:
    #virtual-host-name或secure-virtual-host-name都可以
    virtual-host-name: serverName

自定义配置

在Spring Cloud中,Ribbon的默认配置如下:

BeanType BeanName 默认类 作用
IClientConfig ribbonClientConfig DefaultClientConfigImpl 读取配置
IRule ribbonRule ZoneAvoidanceRule 负载均衡规则,选择实例
IPing ribbonPing DummyPing
(该类什么都不干,认为每个实例都可用,都能ping通)
筛选掉ping不通的实例
ServerList<Server> ribbonServerList Ribbon:ConfigurationBasedServerList
Spring Cloud Alibaba:NacosServerList
交给Ribbon的实例列表
ServerListFilter<Server> ribbonServerListFilter ZonePreferenceServerListFilter 过滤掉不符合条件的实例
ILoadBalancer ribbonLoadBalancer ZoneAwareLoadBalancer Ribbon的入口
ServerListUpdater ribbonServerListUpdate PollingServerListUpdater 更新交给Ribbon的List的策略

负载均衡的八种算法:

规则名称 作用
AvailabilityFilteringRule 过滤掉一直连接失败的被标记为circuit tripped(电路跳闸)的后端Service,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤Server的逻辑,其实就是检查status的记录的各个Server的运行状态
BestAvailableRule 选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过
RandomRule 随机选择一个Server
ResponseTimeWeightedRule 已废弃,作用同WeightedResponseTimeRule
RetryRule 对选定的负责均衡策略机上充值机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server
RoundRobinRule 轮询选择,轮询index,选择index对应位置Server
WeightedResponseTimeRule 根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低
ZoneAvoidanceRule (默认是这个)负责判断Server所Zone的性能和Server的可用性选择Server,在没有Zone的环境下,类似于轮询(RoundRobinRule)

使用java代码自定义配置(不推荐)

创建Ribbon配置类

@Configuration
public class RibbonConfiguration {
    @Bean
    public IRule ribbonRule() {
        //负载均衡规则改为随机
        return new RandomRule();
    }
}

使用配置类

@Configuration
@RibbonClient(name = "eureka-client-producer",configuration = RibbonConfiguration.class)
public class TestConfiguration {
}

@RibbonClient中
name的值为特定的Ribbon Client自定义配置(生产者的虚拟主机名)
configration的值指定Ribbon的配置类

使用属性自定义配置

配置属性的方式比Java代码配置的方式优先级更高,这种方式比使用Java代码配置的方式更加方便。

支持的属性如下,配置的前缀是<clientName>.ribbon.。其中<clientName>是Ribbon Client的名称,如果省略,则表示全局配置。

  • NFLoadBalancerClassName: 配置ILoadBalancer该接口实现类
  • NFLoadBalancerRuleClassName: 配置IRule该接口实现类
  • NFLoadBalancerPingClassName: 配置Iping该接口实现类
  • NIWSServerListClassName: 配置ServerList该接口实现类
  • NIWSServerListFilterClassName: 配置ServiceListFilter该接口实现类

使用如下形式表示对Ribbon Clienteureka-client-producer使用RandomRule负载均衡规则:

eureka-client-producer:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

使用如下形式表示对所有Ribbon Client使用RandomRule负载均衡规则:

ribbon:
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

饥饿加载

Spring Cloud会为每个名称的Ribbon Client维护一个应用程序上下文,这个上下文默认是懒加载的。指定名称的Ribbon Client第一次请求时,对应的上下文才会被加载,因此,首次请求往往会比较慢。
在消费者配置文件中加上如下配置:

ribbon:
  eager-load:
    enabled: true
    clients: client1,client2

这样对名为client1和client2的Ribbon Client,将在启动时就加载对应的子应用程序上下文,从而提高首次请求的访问速度。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!