目录

[TOC]

为了实现微服务架构的高可用性,一般在生产环境中,各个微服务会部署多个实例。这里我们需要用到负载均衡,将服务消费者的请求分摊到多个服务提供者实例上。

Ribbon

Ribbon 是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。Ribbon配置好后,它可以根据如轮询,随机等负载均衡算法自动帮助服务消费去请求。在Spring Cloud中,Ribbon 与Eureka可以很好的配合 ,Ribbon向Eureka注册后可以自动从Eureka中获取服务提供者的地址列表,然后基于某种负载均衡算法去请求其中一个服务提供者实例。

集成Ribbon

在Spring Cloud中使用Ribbon很简单,只需要做一点小修改。
微服务简单实例–电影购票 中的服务消费者为基础进行修改。
##添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

由于 Eureka已经包含了Ribbon 所以这里其实不需要添加上面这个依赖了。

添加注解

还需要为RestTemplate添加@LoadBalanced注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@EnableDiscoveryClient
@SpringBootApplication
public class MicroserviceConsumerMovieRibbonApplication {

/**
* @Bean 是一个方法注解,作用是实例化一个Bean并使用该方法的名称命名。在本例中,添加@Bean注解的restTemplate()方法,等价于RestTemplate restTemplate = new RestTemplate();
* @LoadBalanced 可以为RestTemplate整合Ribbon 使其具备负载均衡的能力。
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}

public static void main(String[] args) {
SpringApplication.run(MicroserviceConsumerMovieRibbonApplication.class, args);
}
}

修改Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
public class UserController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;


@GetMapping("/user/{id}")
public User findById(@PathVariable Long id){
return this.restTemplate.getForObject("http://microservice-provider-user/" + id,User.class);
}

@GetMapping("/log-user-instance")
public void logUserinstance(){
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
UserController.LOGGER.info("{}:{}:{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
}
}

这里需要把请求地址改成 http://microservice-provider-user/ 。microservice-provider-user是用户微服务(服务提供者)的虚拟主机名。当Ribbon与Eureka配合使用时,会自动将虚拟主机名映射成微服务的网络地址。在新增的方法logUserinstance() 方法中使用LoadBalancerClient 的API更加直观的获取当前选择的用户微服务节点。
注意需要在服务提供者的配置文件中添加其虚拟主机名,并且命名不能使用 _ :

1
2
3
spring:
application:
name: microservice-provider-user

测试

我们启动前文中 微服务学习笔记 –使用Spring Cloud Eureka实现服务注册与发现 的一个Eureka项目,启动多个服务提供者,因为是在本地做测试,需要把端口改成不一样的,避免端口占用。最后启动修改后的服务消费者。查看Eureka界面:
微信截图_20180806151100.png
可以看到在Eureka上注册了三个服务提供者,分别使用了不同的端口号。另外还注册了集成Ribbon后的服务消费者。
访问localhost:8010/user/1 可以请求到数据
微信截图_20180806155709.png
多次请求后后台可以看到请求会随机分配给不同的服务提供者。
微信截图_20180806155835.png
可以通过访问 http://localhost:8010/log-user-instance 更加直观的查看负载均衡效果。
多次访问 http://localhost:8010/log-user-instance ,查看后台日志如下:
微信截图_20180806160158.png