Ribbon自定义负载均衡策略

一、前言

在上一篇博客中,小编向大家介绍了负载均衡工具Ribbon,是不是很颠覆呀,是不是很好用呀。从中大家有没有感觉到他的负载均衡策略呀,对的,Ribbon内置的默认策略是轮询。在这篇博客中,小编就带大家领略一下Ribbon自定义策略。

二、Ribbon的负载均衡策略有哪些?

Ribbon负载均衡策略

首先上面的这张图是Ribbon选择策略,我们使用的策略重点是最下面的6个子类:

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

三、自定义策略

这里我借鉴上一篇博客的框架,对ribbon模块进行修改:假定这次修改为随机访问RandomRule。

3.1 设置单一服务的负载均衡策略

3.1.1 修改配置文件

在配置文件中设置指定单一服务的负载均衡策略。 这种方式用于设置单一服务的负载均衡策略。

spring.application.name=ribbon-consumer
server.port=9000

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

# HELLO-SERVICE是服务应用名
HELLO-SERVICE.ribbon.NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3.1.2 启动类

package com.johnfnash.learn.springcloud.ribbon.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	public static void main(String[] args) {
		SpringApplication.run(RibbonConsumerApplication.class, args);
	}

}

3.1.3 编写 controller

package com.johnfnash.learn.springcloud.ribbon.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {

	@Autowired
	RestTemplate restTemplate;

	@RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
	public String helloConsumer(){
		return restTemplate.getForEntity("http://HELLO-SERVICE/hi?name=xxx", String.class).getBody();
	}

	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String hello(){
		return restTemplate.getForEntity("http://HELLO-SERVICE-2/hi?name=xxx", String.class).getBody();
	}
	
}

3.1.4 运行

分别对 调用 hello-service 服务的 ribbon-consumer 接口 和 调用非 hello-service 服务的 hello 接口进行访问,运行结果是前者是随机访问的,而后者则使用的默认的轮询方式,两者结果明显不一样。

3.2 设置所有服务访问的负载均衡策略

3.2.1 启动类

直接在启动类中定义负载均衡策略相应对象。这样服务访问时都会使用该负载均衡策略。

package com.johnfnash.learn.springcloud.ribbon.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	// 定义负载均衡策略
	@Bean
	public IRule ribbonRule() {
		return new RandomRule();
	}
	
	public static void main(String[] args) {
		SpringApplication.run(RibbonConsumerApplication.class, args);
	}

}

3.2.2 controller

使用 3.1.3 中的 controller 定义

3.2.3 测试

分别对 调用 hello-service 服务的 ribbon-consumer 接口 和 调用非 hello-service 服务的 hello 接口进行访问,运行结果是两者是随机访问的。

四、小结

通过这次的使用,可以对比Dubbo的负载均衡策略,有兴趣的通知可以了解一下。dubbo也有loadbalance 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用。所以一通百通。

参考

  1. SpringCloud-Ribbon(自定义负载均衡算法)

猜你喜欢

转载自blog.csdn.net/xxc1605629895/article/details/89045566