5.Netflix Ribbon(客服端负载均衡) 您所在的位置:网站首页 ribbon负载均衡策略默认 5.Netflix Ribbon(客服端负载均衡)

5.Netflix Ribbon(客服端负载均衡)

2023-05-20 10:29| 来源: 网络整理| 查看: 265

目录

1. 微服务基本介绍

2. Netflix Eureka(服务注册/发现)基本介绍

3. Netflix Eureka基本使用

4. Netflix Eureka参数配置项详解

5. Netflix Ribbon负载均衡

6. Netflix Feign远程调用

7. Netflix Hystrix(断路器)

8. Ribbon、Feign、Hystrix之间关系

9. Netflix Zuul(服务网关)

10. Netflix Zuul(服务网关)基本使用

11. Netflix Zuul过滤器(ZuulFilter)

12. 分布式配置(Spring Cloud Config)

Netflix Ribbon(客服端负载均衡) 目录Netflix Ribbon(客服端负载均衡)什么是负载均衡?(1)集中式负载均衡(服务器负载均衡)(2)进程内负载均衡(客户端负载均衡) Ribbon核心机制ILoadBalancer接口(核心接口)IRule接口IPing接口LoadBalancerStats类 Ribbon负载均衡策略(7种)(1)轮询策略(默认)(2)权重轮询策略(3)随机策略(4)最少并发数策略 Ribbon负载均衡基本实现(默认均衡策略)使用@LoadBalanced注解和RestTemplate1.导入依赖(pom.xml)2.修改配置文件3.对访问Rest资源的Bean加上@LoadBalanced负载均衡注解4.主程序启动上添加@EnableDiscoveryClient注解开启Eureka服务发现5.在控制器中注入RestTemplate并调用远程服务 使用@RibbonClient注解1.使用@Configuration配置策略2.启动类上,使用@RibbonClient注解 更改默认的负载均衡策略算法?

Netflix Ribbon(客服端负载均衡)

Spring Cloud Ribbon是一个基于Netflix Ribbon实现的HTTP和TCP的客服端负载均衡工具。它不像Spring Cloud的服务注册中心、配置中心、API 网关那样独立部署,但是它几乎存在于每个Spring Cloud微服务中。包括Feign提供的声明式服务调用也是基于该Ribbon实现的

Ribbon默认提供很多种负载均衡算法,例如轮询、随机等等。甚至包含自定义的负载均衡算法

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。在配置文件中列出负载均衡所有的机器,Ribbon会自动基于某种规则(如简单轮询、随机连接等等)去连接这些机器。Ribbon客户端组件提供了一列完善的配置项(如连接超时、重试等等),也可以很容易的使用Ribbon实现自定义的负载均衡算法

什么是负载均衡?

负载均衡(Load Balance,简称LB),在微服务或分布式集群中经常用到的一种功能;就是将用户的请求以某种规则平摊到多个服务器上,从而达到系统的高可用

常见的负载均衡有软件例如Nginx、LVS等等,硬件F5等等。相应的在中间件,例如Dubbo和Spring Cloud中均提供了负载均衡,Spring Cloud的负载均衡算法可以自定义

目前业界主流的负载均衡方案可分成两类:

(1)集中式负载均衡(服务器负载均衡)

即在服务的consumer(消费方)和provider(提供方)之间使用独立的负载均衡设施(可以是硬件,如F5;也可以是软件,如nginx),由该设施负责把访问请求通过某种策略转发至provider 在这里插入图片描述 在这里插入图片描述

(2)进程内负载均衡(客户端负载均衡)

将负载均衡逻辑集成到服务消费方(consumer),由消费方从服务注册中心获取有那些服务地址可用,然后消费方从这些地址中选择一个合适的服务器。(Ribbon属于进程内负载均衡,它只是一个类库,集成于服务消费方进程,消费方通过它来获取到服务提供方的地址)

在这里插入图片描述 在这里插入图片描述

Ribbon核心机制

客户端负载均衡要做到: ①服务列表中有那些服务 ②如何从这些服务中选择一个进行调用

ILoadBalancer接口(核心接口)

Ribbon的核心接口ILoadBalancer就是围绕着两个问题来设计的,其最基本的实现类是BaseLoadBalancer

ILoadBalancer是定义软件负载平衡器操作的接口。典型的负载平衡器最少需要一组服务器来进行负载平衡,一种将特定服务器标记为不旋转的方法,以及从现有服务器列表中选择服务器的调用

public interface ILoadBalancer { void addServers(List var1); // 加载服务列表 Server chooseServer(Object var1); // 从负载均衡器中选择服务器 void markServerDown(Server var1); // 标记一个服务不可用 @Deprecated List getServerList(boolean var1); // 获取当前服务器列表 List getReachableServers(); //获取当前可用的服务列表 List getAllServers(); // 获取所有服务列表 } IRule接口

负载均衡策略,可以插件化的为负载均衡提供各种适用的负载均衡算法。IRule包含3个方法

public interface IRule { Server choose(Object var1); // 根据key获取后台服务 void setLoadBalancer(ILoadBalancer var1); // 设置ILoadBalancer ILoadBalancer getLoadBalancer(); //获取ILoadBalancer }

如何选择一个服务是否通过,是由IRule实现的。 动态加载后端服务列表:通过DynamicServerListLoadBalancer类实现的,是BaseLoadBalancer的子类

public class BaseLoadBalancer extends AbstractLoadBalancer implements PrimeConnectionListener, IClientConfigAware {} public class DynamicServerListLoadBalancer extends BaseLoadBalancer {} IPing接口

判断目标服务是否存活。该接口中只有一个isAlive()方法,通过对服务器发出IPing操作来获取服务响应,从而判断服务是否可用。

public interface IPing { boolean isAlive(Server var1); } LoadBalancerStats类

记录负载均衡使用时运行信息,用来作为负载均衡策略的运行时输入。

public class LoadBalancerStats implements IClientConfigAware {} Ribbon负载均衡策略(7种)

分为:静态负载均衡算法、动态负载均衡算法

静态负载均衡算法 代表是:随机算法和轮询算法

动态负载均衡算法 典型的动态算法包括:最少连接算法、服务调用延时算法、源IP哈希算法

(1)轮询策略(默认)

策略对应类名:RoundRobinRule 实现原理:轮询策略表示每次都顺序取下一个provider 比如:一共有5个provider(集群),第1次取 provider1,第2次取provider2,第3次取provider3,以此类推。

(2)权重轮询策略

策略对应类名:WeightedResponseTimeRule 实现原理:根据每个provider(服务提供者)的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越低。 原理:一开始为轮询策略,并开启一个计时器,每30秒收集一次每个provider的平均响应时间,当信息足够时,给每个provider附上一个权重,并按权重随机选择provider,高权越重的provider会被高概率选中

(3)随机策略

策略对应类名:RandomRule 实现原理:从provider列表中随机选择一个

(4)最少并发数策略

策略对应类名:BestAvailableRule 实现原理:选择正在请求中的并发数最小的provider,除非这个provider在熔断中。 会过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

(5)重试策略 策略对应类名:RetryRule 实现原理:其实就是轮询策略的增强版。先按照轮询策略(RoundRobinRule)获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务

轮询策略:服务不可用时不做处理 重试策略:服务不可用时会重新尝试集群中的其他节点

(6)可用性敏感策略 策略对应类名:AvailabilityFilteringRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态和并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问

实现原理:过滤性能差的provider 第一种:过滤掉在Eureka中处于一直连接失败的provider(服务)。 第二种:过滤掉高并发(繁忙)的 provider。

(7)区域敏感性策略 策略对应类名:ZoneAvoidanceRule 实现原理:以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的 provider。 如果这个IP区域内有一个或多个实例不可达或响应变慢,都会降低该IP区域内其他IP被选中的权重

Ribbon负载均衡基本实现(默认均衡策略)

Ribbon和Eureka整合后服务消费方可以直接调用服务而不用再关心提供服务的地址以及提供服务的端口号。Ribbon其实就是一个软负载均衡的客户端软件,它可以和其它所需请求的客户端结合使用,和Eureka结合只是其中的一个实例

两种方式的前提都是通过Eureka提供DiscoveryClient工具类查找注册在Eureka的服务(拉取服务) 在这里插入图片描述

使用@LoadBalanced注解和RestTemplate

服务消费者直接通过使用被@LoadBalanced注解修饰过的RestTemplate就可以自动实现服务调用过程中的负载均衡功能

1.导入依赖(pom.xml) org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-ribbon 2.修改配置文件 #web访问端口 server.port=8001 #应用名 spring.application.name=eureka-client #此实例的主机名 eureka.instance.hostname=localhost #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着。默认为30秒 eureka.instance.lease-renewal-interval-in-seconds=10 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒 eureka.instance.lease-expiration-duration-in-seconds=30 #以IP地址注册到服务中心,相互注册使用IP地址 eureka.instance.prefer-ip-address=true #此实例注册到eureka服务端的唯一的实例ID。 #其组成为${spring.application.name}:${spring.application.instance_id:${random.value}} eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}} #注册中心地址。连接eureka server的地址:将本服务注册到eureka server上(defaultZone) eureka.client.service-url.defaultZone=http://localhost:8080/eureka,http://localhost:8090/eureka #是否添加到注册中心,默认为true eureka.client.register-with-eureka=true #此客户端是否获取eureka服务器注册表上的注册信息,默认为true eureka.client.fetch-registry=true #表示eureka client间隔多久去拉取服务器注册信息,默认为30秒 eureka.client.registry-fetch-interval-seconds=20 3.对访问Rest资源的Bean加上@LoadBalanced负载均衡注解 @Bean @LoadBalanced //使用负载均衡机制 public RestOperations restTemplate(){ //RestTemplate实现了RestOperations接口 return new RestTemplate(); }

原理:使用了这个注解以后,会在restTemplate里面通过restTemplate.setInterceptors放入拦截器LoadBalancerInterceptor,这个过滤器会在请求远程成接口的时候动态判断请求的域是不是负载 负载均衡器中服务的地址。如果是,那么就会代理使用这个负载均衡器来调用

利用RestTempllate的LoadBalancerInterceptor拦截器,Spring可以对restTemplate bean进行定制,加入loadbalance拦截器进行ip:port的替换,也就是将请求的地址中的服务逻辑名转为具体的服务地址

@LoadBalanced注解就是个RestTemplate添加一种修饰,以便通过拦截的方式将代码执行流程导向负载均衡客户端LoadBalacneClient。

事实上,在Ribbon中存在一个LoadBalancerAutiConfiguration类,即LoadBalancer的自动配置类。在该类中首先维护了一个被@LoadBalance修饰的TestTemplate对象列表,在初始化的过程中,对目标RestTemplate增加一个LoadBalancerInterceptor用于实现拦截,而在他的拦截方法上本质是使用LoadBalanceClent来执行真正的负载均衡

4.主程序启动上添加@EnableDiscoveryClient注解开启Eureka服务发现

@EnableDiscoveryClient注解也可以

@SpringBootApplication @EnableEurekaClient //开启服务注册发现功能 public class SpringcloudconsumerApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudconsumerApplication.class, args); } } 5.在控制器中注入RestTemplate并调用远程服务 @RestController public class UserController { @Autowired private RestOperations restTemplate; @GetMapping("/userno1") public User getUsersFirst(){ User[] users = restTemplate.getForObject("http://user-provider/users",User[].class); return users[0]; } } 使用@RibbonClient注解

通过@RibbonClient注解实现更细粒度的客户端负载均衡配置

自动化配置 由于Ribbon中定义的每一个接口都有多种不同的策略实现,同时这些接口之间又有一定的依赖关系,Spring Cloud Ribbon中的自动化配置能够很方便的自动化构建接口的具体实现

接口如下:

接口描述IClientConfigRibbon 的客户端配置。默认采用com.netflix.client.config.DefaultClientConfigImpl实现IRuleRibbon的负载均衡策略。默认采用com.netflix.loadbalancer.ZoneAvoidanceRule实现,该策略能够在多区域环境下选择最佳区域的实例进行访问IPingRibbon的实例检查策略。默认采用com.netflix.loadbalancer.NoOpPing实现。该检查策略是一个特殊的实现,实际上他并不会检查实例是否可用,而是始终返回 true ,默认认为所有服务实例都是可以使用ServerList服务实例清单的维护机制。默认采用com.netflix.loadbalancer.ConfigurationBasedServerList实现ServerListFilter服务实例清单过滤机制。默认采用netflix.ribbon.ZonePreferenceServerListFilter实现,该策略能够优先过滤出与请求调用方处理同区域的服务实现ILoadBalancer负载均衡器。默认采用com.netflix.loadbalancer.ZoneAwareLoadBalancer实现,他具备了区域感知的能力

这些自动化配置内容是在没有引入Spring Cloud Eureka等服务治理框架时如此,在同时引入Eureka和Ribbon依赖时,自动化配置会有一些不同。通过自动化配置的实现,可以轻松的实现客户端的负载均衡,同时,针对一些个性化的需求,也可以方便的替换上面的这些默认实现

1.使用@Configuration配置策略 @Configuration public class RibbonConfiguration { @Bean public IRule ribbonRule(IClientConfig clientConfig) { return new WeightedResponseTimeRule(); } }

注意: (1)Ribbon配置类不能包含在主应用程序上下文的@ComponentScan中,否则该类中的配置信息就被所有的@RibbonClient共享 (2)如果只想自定义某一个Ribbon客户端的配置,必须防止@Configuration注解的类所在的包与@ComponentScan扫描的包重叠,或应显示指定@ComponentScan不扫描@Configuration类所在的包

2.启动类上,使用@RibbonClient注解

使用@RibbonClient注解来实现更细粒度的客户端配置,在启动类上,使用@RibbonClient注解来指定服务使用WebServiceRibbonConfiguration配置

@RibbonClient (name = "client-server", configuration = RibbonConfiguration.class) @EnableDiscoveryClient @SpringBootApplication public class ConsumerHelloserviceApplication { public static void main(String[] args) { SpringApplication.run(ConsumerHelloserviceApplication.class, args); } @LoadBalanced @Bean public RestTemplate createRestTemplate() { return new RestTemplate(); } } @RibbonClient属性描述nameRibbon Client自定义配置configuration指定Ribbon的配置类

注意:如果需要使服务单独配置,那么配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,@SpringBootApplication 注解中就包含了 @ComponentScan 注解,因此必须使配置类处于不同的包以及子包。

如果需要设置默认配置或者多个@RibbonClient 注解,可以使用 @RibbonClients 注解,其 defaultConfiguration 可以设置默认的自定义配置,配置类不限定所属包,value 可以设置多个 @RibbonClient 注解

@RibbonClients (defaultConfiguration = RibbonConfiguration.class) 更改默认的负载均衡策略算法?

更改Netflix Ribbon默认负载均衡,只需要在原来的Java配置中增加IRule配置,并返回一种负载策略(注入至容器中)

@Configuration public class RibbonConfig { @Bean public IRule iRule(){ return new RandomRule(); } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有