前言
我们这里准备了2组服务:
* 2个microservice-springcloud-user服务,端口分别为7902和7904;
* 2个microservice-springcloud-user2服务,端口分别为7903和7905;
我们想实现的效果是:microservice-springcloud-user服务随机访问,microservice-springcloud-user2服务顺序访问。下面我们通过代码的方式来实现。
创建Ribbon规则
package com.tommy.config;
@Configuration
public class RibbonChooseConfiguration {
@Bean
public IRule ribbonRule(IClientConfig config) {
return new RandomRule();
}
}
这里指定的规则是随机。
The FooConfiguration has to be @Configuration but take care that it is not in a @ComponentScan for the main application context, otherwise it will be shared by all the @RibbonClients. If you use @ComponentScan (or @SpringBootApplication) you need to take steps to avoid it being included (for instance put it in a separate, non-overlapping package, or specify the packages to scan explicitly in the @ComponentScan).
上面是Spring Cloud官方文档的原文,这里的config类所在的包有一定讲究,就是你的包不能被@ComponentScan或者@SpringBootApplication扫描到。官方文档Ribbon部分:http://cloud.spring.io/spring-cloud-static/Edgware.SR1/single/spring-cloud.html#spring-cloud-ribbon
在应用启动类上配置访问规则
package com.tommy.springcloud;
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "microservice-springcloud-user",configuration = RibbonChooseConfiguration.class)
public class App
{
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main( String[] args )
{
SpringApplication.run(App.class,args);
}
}
这里指定microservice-springcloud-user使用的规则是RibbonChooseConfiguration定义的规则,也就是随机的。
测试Controller修改
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/user/{userId}")
public User getUser(@PathVariable Long userId) {
return restTemplate.getForObject("http://microservice-springcloud-user/sample/" + userId,User.class);
}
@GetMapping(value = "/test")
public String test() {
ServiceInstance serviceInstance = loadBalancerClient.choose("microservice-springcloud-user");
System.out.println(serviceInstance.getServiceId()+"-->"+serviceInstance.getHost()+":"+serviceInstance.getPort());
ServiceInstance serviceInstance2 = loadBalancerClient.choose("microservice-springcloud-user2");
System.out.println(serviceInstance2.getServiceId()+"-->"+serviceInstance2.getHost()+":"+serviceInstance2.getPort());
return "hello,world";
}
}
getUser()方法仍然访问microservice-springcloud-user服务,test()方法则2个服务都访问,打印服务的id、ip和端口。
测试
- 1.开启2个microservice-springcloud-user服务,端口分别为7902和7904;
- 2.开启2个microservice-springcloud-user2服务,端口分别为7903和7905;
- 3.开启microservice-springcloud-movie,进行测试;
4.浏览器输入http://localhost:7901/user/1,查看控制台:
可以看到,microservice-springcloud-user一个控制台打印了3条SQL,一个1条SQL,说明访问是随机的。而我们在代码中指定了Ribbon访问microservice-springcloud-user的规则是随机的,所以说明规则生效了。5.浏览器输入http://localhost:7901/test,访问6次
可以看到,microservice-springcloud-user是随机访问的,microservice-springcloud-user2是轮询。