Spring Cloud的负载均衡Ribbon,负载均衡策略

RestTemplate简介

RestTemplate是Spring Resources中一个访问第三方RestFul api接口的网络请求框架。RestTemplate 的设计原则和其他Spring Template(例如JdbcTemplate、JmsTemplate)类似,都是为执行复杂任务提供了一个具有默认行为的简单方法。

RestTemplate是用来消费REST服务的,所以RestTemplate的主要方法都与REST的Http协议的一些方法紧密相连,例如HEAD、GET、POST、PUT、DELETE、OPTIONS等方法,这些方法在RestTemplate类对应的方法为headForHeaders()、getForObject()、postForObject()、put()、delete()等。

maven依赖:

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>

    <version>2.0.1.RELEASE</version>

</dependency>

application启动类注入bean:

@Bean

@LoadBalanced

RestTemplate restTemplate(){

   return new RestTemplate();

}

service层引用注入实例:

@Autowired

private RestTemplate restTemplate;

User user = restTemplate.getForObject("http://weather/getUser", User.class);
return user.getName();

RestTemplate的使用很简单,它支持xml、json数据格式,默认实现序列化,可以自动将JSON字符串转化为实体,如上代码,可以将返回的json字符串转换成User对象。

负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式,一种是独立进行单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如Ngnix。另一种是将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提供者的信息列表,有了列表,通过负载均衡策略将请求分摊到多个服务提供者,从而达到负载均衡的目的。

LoadBalancerClient简介

负载均衡的核心类是LoadBalancerClient,它可以获取负载均衡的服务提供者的实例信息。比如注册一个服务weather,这个服务weather监听2个端口8770/8764,并启动这两个服务。那么在Eureka server上会注册2个实例,当你使用负载均衡的时候,LoadBalancerClient的choose("weather")方法可以轮流得到client的两个服务实例的信息,交替请求这两个服务。

8764实例

8770实例

访问eureka server,weather的2个实例已经注册成功

访问ribbon 

 

我们发现,同样访问ribbon接口,结果是从8764和8770交替返回的结果,这样就实现了请求分发,负载均衡。

LoadBalancerClient接口继承了ServiceInstanceChooser,RibbonLoadBalancerClient实现了LoadBalancerClient,RibbonLoadBalancerClient是非常重要的类,最终的负载均衡请求处理由它来执行。choose()方法用于选择具体服务实例。choose()方法通过getServer()方法获取实例,经过源码跟踪最终通过ILoadBalancer类去选择实例。

IRule有很多具体的实现类,这些根据不同的算法和逻辑来处理负载均衡的策略。

IPing用于向server发送"ping",来判断该server是否有响应,从而判断server是否可用,它有一个isAlive()方法。

EurekaClient的实现类DiscoveryClient,DiscoveryClient具有服务注册、获取服务注册列表等功能。

Ribbon的使用,这里使用了@LoadBalanced负载均衡。

Ribbon结合RestTemplate

controller

Springcloud在封装Ribbon的时候,提供了OkHttpClient和HttpClient请求实例。

Ribbon实现负载均衡的三点是:

服务发现:就是依据服务的名字,把该服务下的所有实例都找出来

服务选择规则:依据规则策略,如何从多个服务中找出要使用的服务

服务监听:检测失效服务,做到高效剔除

Ribbon的主要组建有ServerList、IRule、ServerListFilter,整个首先会通过ServerList获得可用服务列表,再通过ServerListFilter,过滤掉一些地址,最后剩下的地址,通过IRule,作为最终目标结果。

ILoadBalance负载均衡器

ribbon作为一个客户端提供负载均衡功能的服务,内部提供一个ILoadBalance的接口,代表负载均衡的操作,比如添加服务器、选择服务器、获取所有服务器列表、获取可用服务器列表等等。

负载均衡器是从EurekaClient(EurekaClient的实现类是DiscoveryClient)获取服务信息,根据IRule去路由,并且根据Ping判断服务的可用性。负载均衡器平均10秒去EurekaClient获取服务注册信息。

完整过程是:

LoadBalancerClient(RibbonLoadBalancerClient是实现类)在初始化的时候(execute方法),会通过ILoadBalance(BaseLoadBalancer是实现类)向Eureka注册中心获取服务注册列表,并且每10s一次向EurekaClient发送“ping”,来判断服务的可用性,如果服务的可用性发生了改变或者服务数量和之前的不一致,则从注册中心更新或者重新拉取。LoadBalancerClient有了这些服务注册列表,就可以根据具体的IRule来进行负载均衡。

IRule是负载均衡器的策略对象

 

其中RandomRule表示随机策略,随机从服务器中选择一个

RoundRobinRule表示轮询策略(默认采用轮询策略),循环使用服务器,比如5台服务器a,b,c,d,e,轮循使用

WeightedResponseTimeRule表示加权策略,继承RoundRobinRule,开始的时候没有权重列表,采用父类的轮循方式,有一个默认30秒更新一次权重的定时任务,该任务根据实例反应时间来更新权重列表,choose方式做的事情是,用一个(0,1)的随机double数乘以最大的权重得到randomWeight,然后遍历权重列表,找出第一个比randomWeight更大的实例下标,返回该实例。

 

BestAvailableRule表示请求数最少策略等等 

默认采用是轮询方式,如果想改变负载均衡策略,可以重新注入bean,这种方式对Feign也有效

@Bean
public IRule ribbonRule() {
    return new BestAvailableRule();
}

总体有7种策略

策略名策略声明策略描述实现说明
BestAvailableRulepublic class BestAvailableRule extends ClientConfigEnabledRoundRobinRule选择一个最小的并发请求的server逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRulepublic class AvailabilityFilteringRule extends PredicateBasedRule过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRulepublic class WeightedResponseTimeRule extends RoundRobinRule根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成status时,使用roubine策略选择server。
RetryRulepublic class RetryRule extends AbstractLoadBalancerRule对选定的负载均衡策略机上重试机制。在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRulepublic class RoundRobinRule extends AbstractLoadBalancerRuleroundRobin方式轮询选择server轮询index,选择index对应位置的server
RandomRulepublic class RandomRule extends AbstractLoadBalancerRule随机选择一个server在index上随机,选择index对应位置的server
ZoneAvoidanceRulepublic class ZoneAvoidanceRule extends PredicateBasedRule复合判断server所在区域的性能和server的可用性选择server使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

 Ribbon架构图

1258b858-c697-32e3-8f9e-b2623f7c6862.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值