**
spring cloud Ribbon 自定义规则
**
spring cloud Ribbon 自定义规则分为两种方式,第一种是通过代码配置,第二种是通过配置文件;
第一种:通过代码配置:
创建注册中心,服务提供者,服务调用者,这里不再详述,本文是在创建好这些基础之上,实现自定义规则,本文自定义的规则比较简单,只是为了测试怎样实现自定义规则,自定义规则是始终调用第一个URl服务,同时本文也自定义了ping,
补充知识,springBoot 读取application.properties的顺序:
项目根目录的config 目录。
项目根目录。
项目classpath 下的config 目录。
项目classpath 根目录。
本文的工程目录结构:
1.创建好以上三个服务后,自定义规则在调用者模块实现,首先创建MyRule类,继承AbstractLoadBalancerRule 类,也可以实现IRule,但是实现这个类,在启动时使用ILoadBalancer 一直不能注入bean ,报空指针异常,所以就继承了它的子类AbstractLoadBalancerRule 。
public class MyRule extends AbstractLoadBalancerRule {
private ILoadBalancer lb;
public MyRule() {
}
@Override
public Server choose(Object o) {
ILoadBalancer lb = getLoadBalancer();
List<Server> servers = lb.getAllServers(); // 获取所有的服务
System.out.println("这是自定义规则类,输出服务器信息:");
for (Server s : servers){
System.out.println("服务器的端口号:"+ s.getHostPort());
}
return servers.get(0); // 始终返回第一个服务
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
2.创建自定义的ping,未设置规则,需要可以自行定义:
public class MyPing implements IPing {
@Override
public boolean isAlive(Server server) {
System.out.println("自定义Ping 类,服务器信息:" + server.getHostPort());
return true;
}
}
3.创建 MyConfig类,注意添加@Configuration注解;
@Configuration //注意添加注解
public class MyConfig {
@Bean
public IRule getRule(){
return new MyRule();
}
@Bean
public IPing getPing(){
return new MyPing();
}
}
@Configuration
@RibbonClient(name="consumer",configuration=MyConfig.class) //name:建议写服务名称 configuration:配置类
public class CloudProviderConfig {
}
4.服务调用者的 controller
@RestController
@Configuration
@RequestMapping("/invoker")
public class InvokerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private SpringClientFactory factory;
@GetMapping("/index")
public String router() {
return restTemplate.getForObject("http://provider/student/index",String.class);
}
}
服务提供者的controller
@RequestMapping("/student")
@RestController
public class StudentHandler {
@Autowired
private StudentRepository studentRepository;
@Value("${server.port}")
private String port;
@GetMapping("/index")
public String index(){
return "当前端口"+this.port;
}
}
服务调用者的application.yml配置类:
server:
port: 8020
启动服务发现输出的当前端口号,始终只有第一个。
第二种方式:配置文件,在application.yml种配置:
1.新建MyRlue类和MyPing类,记得在类上加注解@conponent,遇到问题没有加,怎么配置都无效。
2.在配置文件种配置:
配置文件如下:
server:
port: 8020
spring:
application:
name: consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
consumer: #这里写服务调用者应用名和提供者应用名都生效。
ribbon:
NFLoadBalancerRuleClassName: consumer.cloud.MyRule
NFLoadBalancerPingClassName: consumer.cloud.MyPing