前言

我们这里准备了2组服务:

  • 2个microservice-springcloud-user服务,端口分别为7902和7904;
  • 2个microservice-springcloud-user2服务,端口分别为7903和7905;
    我们想实现的效果是:microservice-springcloud-user服务随机访问,microservice-springcloud-user2服务顺序访问。下面我们通过代码的方式来实现。

创建Ribbon规则

1
2
3
4
5
6
7
8
9
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

在应用启动类上配置访问规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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是轮询。