1. 修改 microservicecloud-consumer-dept-80
2. 主启动类添加 @RibbonClient
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)3. 配置细节 这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊化定制的目的了。主配置类的注解就是包含@ComponentScan,所以自定义的类不能再主配置类所在的包下以及子包下!
4. 步骤
(1)自定义类
新建package com.atguigu.myrule,新建自定义Robbin规则类
package com.atguigu.myrule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; @Configuration public class MySelfRule { @Bean public IRule myRule() { return new RandomRule();//Ribbon默认是轮询,我自定义为随机 } }(2)修改主配置类
package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import com.atguigu.myrule.MySelfRule; @SpringBootApplication @EnableEurekaClient @RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class) public class DeptConsumer80_App { public static void main(String[] args) { SpringApplication.run(DeptConsumer80_App.class, args); } }(3)测试
http://localhost/consumer/dept/list
总结:经过上面的配置完成对于特定的微服务采用特定的负载均衡策略
5. 自定义策略
(1)策略:依旧轮询策略,但是加上新需求,每个服务器要求被调用5次。也即以前是每台机器一次,现在是每台机器5次
(2)解析源码
https://github.com/Netflix/ribbon/blob/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/RandomRule.java
(3)参考源码修改为我们需求要求的RandomRule_ZY.java
package com.atguigu.myrule; import java.util.List; import java.util.Random; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; public class RandomRule_ZY extends AbstractLoadBalancerRule { private int total = 0; //总共被调用的次数,目前要求每台被调用5次 private int currentIndex = 0;//当前提供服务的机器号 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; } // int index = rand.nextInt(serverCount); // server = upList.get(index); 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; } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { } }(4)MySelfRule.java
package com.atguigu.myrule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; @Configuration public class MySelfRule { @Bean public IRule myRule() { //return new RandomRule();//Ribbon默认是轮询,我自定义为随机 return new RandomRule_ZY();//我自定义为每个机器被访问5次 } }(5)启动测试
http://localhost/consumer/dept/list
【提示】我们可以看到自定义策略,主要在于策略的编写!这里面了解即可。作者水平有限。。。哈~
