自定义负载均衡
-
loadblancer负载均衡包下有一个IRule接口
-
几个实现类,分别是
-
抽象的负载均衡角色
- 获取负载均衡的默认实现
-
可过滤角色
-
public class RoundRobinRule extends AbstractLoadBalancerRule {
-
轮询是比较常用的负载均衡算法,集成于AbstractLoadBalancerRule,所以基于这个来模仿一个自定义负载均衡
-
几个会用到的源码的方法,获取服务个数,下一个服务
-
/*选择,如果lb为空,没有负载均衡*/ public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { log.warn("no load balancer"); return null; } Server server = null; int count = 0; while (server == null && count++ < 10) { List<Server> reachableServers = lb.getReachableServers(); /*获取可达到的服务*/ List<Server> allServers = lb.getAllServers(); /*获取所有服务*/ int upCount = reachableServers.size(); /*大小*/ int serverCount = allServers.size(); if ((upCount == 0) || (serverCount == 0)) { log.warn("No up servers available from load balancer: " + lb); /*没有服务能轮询*/ return null; int nextServerIndex = incrementAndGetModulo(serverCount); server = allServers.get(nextServerIndex); /*下一个服务*/
-
先测试使用它预设的Rule
-
@SpringBootApplication @EnableEurekaClient public class Demo03consumerApplication { @Bean @LoadBalanced public RestTemplate getTestTemplate(){ return new RestTemplate(); } @Bean public IRule iRule(){ return new RandomRule(); } public static void main(String[] args) { SpringApplication.run(Demo03consumerApplication.class, args); } }
-
之后负载均衡就变成RandomRule了
SpringCloud Netflix 官方文档
- https://www.springcloud.cc/spring-cloud-netflix.html
- SpringCloud更新为SpringCloudNetflix,里面有记载自定义Ribbon的演示
- 这里提示了,自定义的Ribbon客户端必须是Configuration,但是不能和主程序在同一级目录
自定义负载均衡实现
-
package com.haoyun.config; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import org.springframework.context.annotation.Configuration; import java.util.List; /** * @author haoyun */ @Configuration public class MyRibbonRule extends AbstractLoadBalancerRule { int total = 0; int reachableServersIndex = 0; /*选择,如果lb为空,没有负载均衡*/ public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { List<Server> reachableServers = lb.getReachableServers(); /*获取可达到的服务*/ List<Server> allServers = lb.getAllServers(); /*获取所有服务*/ int upCount = reachableServers.size(); /*存活服务总数*/ int serverCount = allServers.size(); /*服务总数*/ if ((upCount == 0) || (serverCount == 0)) { /*没有服务能轮询*/ return null; /*upCount ServerCount有一个为0直接返回null*/ } /*每个服务使用3次,做一个计数 * 做一个界限判定*/ if (total < 3 && reachableServersIndex < upCount) { server = allServers.get(reachableServersIndex); for (int i = 0; i < allServers.size(); i++) { System.out.println(allServers.get(i) + "============" + i); } /*下一个服务*/ System.out.println(total + "==================="); total++; if (total == 3) { System.out.println(reachableServersIndex); reachableServersIndex++; } } else { total = 0; if (reachableServersIndex == upCount) { reachableServersIndex = 0; } } if (server == null) { /* Transient. */ Thread.yield(); continue; } if (server.isAlive() && (server.isReadyToServe())) { return (server); } // Next. server = null; } return server; } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { } }
-
加入Configuration注解
-
@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "springCloud-provider" ,configuration = MyRibbonRule.class) /*在微服务启动时去加载自定义的Ribbon类*/ public class Demo03consumerApplication { @Bean @LoadBalanced public RestTemplate getTestTemplate(){ return new RestTemplate(); } //@Bean //public IRule iRule(){ // return new RandomRule(); //} public static void main(String[] args) { SpringApplication.run(Demo03consumerApplication.class, args); } }
-
启动类上指定自定义负载均衡