Ribbon自定义负载均衡策略算法Feign和RestTemplate
原文链接:https://blog.csdn.net/weixin_40991408/article/details/103921299
一. Ribbon 负载均衡策略介绍
看图,不解释
默认 轮询
二. Feign 更改负载均衡策略
项目用 eureka-feign-hystrix-client,参考文章
feign 更改负载就均衡策略 只要在配置文件 application.yml 配置就行,代码如下:
server:
port: 8767
spring:
#配置程序名为eureka-feign-hystrix-client
application:
name: eureka-feign-hystrix-client
eureka:
client:
#服务注册地址
serviceUrl:
#注意: Eureka Server 的注册地址
#将服务提供者注册到三个Eureka Server中去
#defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/
#defaultZone: http://peer1:8001/eureka/
defaultZone: http://localhost:8761/eureka/
feign:
hystrix:
enabled: true #开启 Hystrix 功能
logging:
level:
#feign 接口类的路径(这个配置表示的意思是,在调用 FeignHystrixInter 接口时做debug日志的输出。)
com:
example:
eurekafeignhystrixclient:
inter:
FeignHystrixInter: debug
# 如何配置多个 Feign 接口类 的 调用日志
# FeignHystrixInter2: debug
# FeignHystrixInter3: debug
# FeignHystrixInter4: debug
# Feign 如何结合 Ribbon 切换负载均衡策略算法
eureka-client: # eureka-client 表示作用到哪个微服务
ribbon:
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置规则 重试
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
# 我们也可以指定为其他策略,包括我们自己定义的,只要把相应的包路径写到这即可。
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
# ConnectTimeout: 500 #请求连接超时时间
# ReadTimeout: 1000 #请求处理的超时时间
# OkToRetryOnAllOperations: true #对所有请求都进行重试
# MaxAutoRetriesNextServer: 2 #切换实例的重试次数
# MaxAutoRetries: 1 #对当前实例的重试次数
三. RestTemplate 中更改负载均衡策略算法
项目用 eureka-ribbon-hystrix-client,参考文章
RestTemplate 更改负载就均衡策略 只要在Ribbon配置类 RibbonConfig 添加代码即可,代码如下:
package com.example.eurekaribbonhystrixclient.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 如何将RestTemplate 和 Ribbon 相结合进行负载均衡?
* 只需要在程序的IOC容器中注入一个 RestTemplate 的 Bean,并在这个 Bean 上加上 @LoadBalanced 注解(负载均衡注解)
* 此时 RestTemplate 就结合 Ribbon 开启了负载均衡功能
*
*/
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* 更改 负载均衡策略算法
* RandomRule #配置规则 随机
* RoundRobinRule #配置规则 轮询
* RetryRule #配置规则 重试
* WeightedResponseTimeRule #配置规则 响应时间权重
* 也可以自定义负载均衡策略的类
* @return
*/
@Bean
public IRule myRule(){
return new RandomRule();
}
}
四.自定义负载均衡策略的类
定义 MyCustomRule 类 继承 AbstractLoadBalancerRule 类,重写父类方法。
例如:要求每台服务器被调用5次才能轮询下一个,也就是说以前每台机器一次,现在每台机器5次。代码如下:
package com.example.eurekaribbonhystrixclient.rule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
* 要求每台服务器被调用5次才能轮询下一个,也就是说以前每台机器一次,现在每台机器5次。
*/
public class MyCustomRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
/**
* Randomly choose from all living servers
*/
//@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
//从服务清单中随机选择一个服务实例
@SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
int total = 0; // 总共被调用的次数,目前要求每台被调用5次
int currentIndex = 0; // 当前提供服务的机器号
while (server == null) {
if (Thread.interrupted()) {
return null;
}
//负载均衡来获得可用实例列表upList和allList
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
/*
* No servers. End regardless of pass, because subsequent passes
* only get more restrictive.
*/
return null;
}
if (total < 5) {
server = upList.get(currentIndex);
total++;
} else {
total = 0;
currentIndex++;
if (currentIndex >= upList.size()) {
currentIndex = 0;
}
}
if (server == null) {
/*
* The only time this should happen is if the server list were
* somehow trimmed. This is a transient condition. Retry after
* yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
//正常情况下,每次都应该可以选择一个服务实例
return server;
}
//随机获取一个随机数
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
}
在Feign中 ,在配置文件application.yml 配置自定义的策略,如图所示:
在RestTemplate,配置自定义的策略,代码如下:
package com.example.eurekaribbonhystrixclient.config;
import com.example.eurekaribbonhystrixclient.rule.MyCustomRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 如何将RestTemplate 和 Ribbon 相结合进行负载均衡?
* 只需要在程序的IOC容器中注入一个 RestTemplate 的 Bean,并在这个 Bean 上加上 @LoadBalanced 注解(负载均衡注解)
* 此时 RestTemplate 就结合 Ribbon 开启了负载均衡功能
*
*/
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* 更改 负载均衡策略算法
* RandomRule #配置规则 随机
* RoundRobinRule #配置规则 轮询
* RetryRule #配置规则 重试
* WeightedResponseTimeRule #配置规则 响应时间权重
* 也可以自定义负载均衡策略的类
* @return
*/
@Bean
public IRule myRule(){
return new MyCustomRule();//自定义的Rule
//return new RandomRule();
}
}