注意说明:自定义的ribbon策略配置不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享。通过查看源代码来看,启动类一般加@SpringBootApplication,而它底封装了@ComponentScan注解,所以自定义的代码文件不能和启动类放在同一个包下。如下图:
UserDefineConfig自定的类不能放在com.ljf.weifuwu.springcloud.ribbon包下面,因为RibbonConsumerApp启动类有@ComponentScan这个注解,且在com.ljf.weifuwu.springcloud.ribbon这个包下面。
解决的办法是:和com.ljf.weifuwu.springcloud.ribbon这个包平级下新建一个config包,将UserDefineConfig配置放到config包下。
1.操作步骤:
config:
package config;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
@Configurable
public class UserDefineConfig {
@Autowired
IClientConfig config;
@Bean
public IRule ribbonRule(IClientConfig config){
return new RandomRule();//随机策略
}
}
启动类:
controller:
package com.ljf.weifuwu.springcloud.ribbon.controller; import com.ljf.weifuwu.springcloud.ribbon.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class RibbonUserController { @Autowired private LoadBalancerClient loadBalancerClient; @Autowired private RestTemplate restTemplate; @GetMapping("/consumer-ribbon/{id}") public User findById(@PathVariable Long id) { // return this.restTemplate.getForObject("http://localhost:7900/eureka-provider/" + id, User.class); return this.restTemplate.getForObject("http://ms-eureka-provider/eureka-provider/" + id, User.class); } @GetMapping("/usedefine-ribbon") public String show(){ ServiceInstance serviceInstance = this.loadBalancerClient.choose("ms-eureka-provider"); System.out.println("随机:" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort()); ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("ms-ribbon-provider"); System.out.println("轮询:" + ":" + serviceInstance2.getServiceId() + ":" + serviceInstance2.getHost() + ":" + serviceInstance2.getPort()); return "1"; } }
访问:启动ms-eureka-sever(8761) , ms-ribbon-consumer(8001),ms-eureka-provider(7901 ),ms-eureka-provider(7900 ),ms-ribbon-provider(8002 ),ms-ribbon-provider(8003).
ms-eureka-provider:使用的是自定义的,随机策略,在启动类进行了配置:
@RibbonClient(name="ms-eureka-provider",configuration = UserDefineConfig.class)
ms-ribbon-provider:使用的是默认,轮询策略。
访问:http://localhost:8001/usedefine-ribbon
查看后台log:
随机::ms-eureka-provider:192.168.1.14:7900 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8002 随机::ms-eureka-provider:192.168.1.14:7900 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8002 随机::ms-eureka-provider:192.168.1.14:7900 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8002 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8002 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7900 轮询::ms-ribbon-provider:192.168.1.14:8002 随机::ms-eureka-provider:192.168.1.14:7900 轮询::ms-ribbon-provider:192.168.1.14:8003 随机::ms-eureka-provider:192.168.1.14:7901 轮询::ms-ribbon-provider:192.168.1.14:8002
通过观察:ms-eureka-provider:7900和7901,实现了随机;ms-ribbon-provider:8002和8003,实现了轮询操作。