Ribbon - Customizing the Ribbon Client
自定义Ribbon算法
自定义Ribbon 官网文档链接 Ribbon github源码地址
<!--ribbon配置--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
在主启动类上加上@RibbonClient
name表示server的名字,configuration表示自定义Ribbon算法的类
@RibbonClient(name = "COULD-DEPT-PROVIDE-DEPT", configuration = MyIrule.class)
package com.amber.springcloud; import com.amber.MyIrule.MyIrule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableEurekaClient @RibbonClient(name = "COULD-DEPT-PROVIDE-DEPT", configuration = MyIrule.class) public class ConsumerDept6001 { public static void main(String[] args){ SpringApplication.run(ConsumerDept6001.class, args); } }
package com.amber.MyIrule; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import java.util.List; import java.util.concurrent.ThreadLocalRandom; /** * A loadbalacing strategy that randomly distributes traffic amongst existing * servers. * * @author stonse * */ public class MyIrule extends AbstractLoadBalancerRule { int currentIndex = 0; int total = 0; /** * Randomly choose from all living servers */ public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; } 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; } //获取当前可用的server // int index = chooseRandomInt(serverCount); //获取所有的server // server = upList.get(index); if (total < 3) { server = upList.get(currentIndex); total ++; } else { total = 0; currentIndex ++; if (currentIndex > allList.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); } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // TODO Auto-generated method stub } }
RandomRule源码地址。修改里面的Choose方法,实现。把原来的每次随机调用,换成每台server调用3次。
Important
自定义Ribbon算法的时候,自定义类不能够方法哦@ComponentScan下。因此MyRule.java不能放在SpringBoot启动类的包以及子包下