微服务架构七:Ribbon客户端的负载均衡
言归正传,我们先看一下问题场景:
在生产系统中,如果我们的服务只有一个实例,如果由于异常或其他原因导致该服务停止,则整个系统将处于宕机状态,系统无法正常运行,为了解决整个问题,我们可以在一个服务器上,开启多个端口不通的服务实例或者在多台服务器上部署端口相同或不通的服务实例,来提供服务。那么与之而来的问题就是来自客户端的请求,我们如何分发到各个服务端实例。负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容。因为负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。这时候就需要引入负载均衡的概念了。
负载均衡分为:客户端负责均衡和服务端负载均衡;我们通常所说的负载均衡都指的是服务端负载均衡,其中分为硬件负载均衡和软件负载均衡。硬件负载均衡主要通过在服务器节点之间按照专门用于负载均衡的设备,比如F5等;而软件负载均衡则是通过在服务器上安装一些用于负载均衡功能或模块等软件来完成请求分发工作,比如Nginx等。
服务端负载均衡架构图:
客户端负责均衡:Ribbon是一个客户端负载均衡器,它有几种负载均衡机制,默认是轮询,我们也可以自定义规则,通过合理的分配网络请求来减小服务器的压力。
言归正传:
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。
利用Ribbon实现客户端的负载均衡,总体流程为:搭建注册中心,服务提供者注册到注册中心,服务消费者注册到注册中心,服务消费者从注册中心获取服务并执行。
第一步:搭建注册中心
参考博客:https://blog.csdn.net/u013310119/article/details/111997007
第二步:创建服务提供者
参考博客:https://blog.csdn.net/u013310119/article/details/112020596
第三步:服务消费者
首先新建一个SpringBoot项目,命名spring-cloud-consumer-ribbon,然后按照下面步骤编写代码即可。
1、pom.xml代码
添加eureka-client的依赖,代码如下
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
<optional>true</optional>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
</dependencies>
-
-
<dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-dependencies</artifactId>
-
<version>Finchley.RELEASE</version><!-- eureka版本 -->
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
</dependencies>
-
</dependencyManagement>
2、启动类代码
配置RestTemplate时候添加@LoadBalanced注解,就代表启动Ribbon,进行负载均衡。
启动类添加注解@EnableEurekaClient,也注册到注册中心,代码如下:
-
@EnableEurekaClient
-
@SpringBootApplication
-
public class RibbonConsumerApplication {
-
-
//当添加@LoadBalanced注解,就代表启动Ribbon,进行负载均衡
-
@LoadBalanced
-
@Bean
-
public RestTemplate restTemplate() {
-
return new RestTemplate();
-
}
-
-
public static void main(String[] args) {
-
SpringApplication.run(RibbonConsumerApplication.class, args);
-
}
-
-
}
3、Controller代码
添加一个Controller,用于调用服务提供者。
-
/**
-
* 消费者Controller
-
*/
-
@Slf4j
-
@RestController
-
@RequestMapping("/consumer")
-
public class RibbonConsumerController {
-
-
@Autowired
-
private RestTemplate restTemplate;
-
-
@Autowired
-
private LoadBalancerClient loadBalancerClient;
-
-
/**
-
* 调用 user微服务
-
*/
-
@GetMapping("getUser")
-
public String getUser(Integer id) {
-
String url = "http://user-service/provider/getUser?id=" + id;
-
return restTemplate.getForObject(url, String.class);
-
}
-
}
4、配置文件
使用yml的配置文件,application.yml配置如下:
-
server:
-
port: 8082 #服务端口
-
eureka:
-
client:
-
serviceUrl:
-
defaultZone: http://localhost:9001/eureka/
-
spring:
-
application:
-
name: user-service-consumer-ribbon
第四步:系统部署、测试
1、启动注册中心,并注册 服务提供者、服务消费者
先访问注册中心http://localhost:9001/,出现下图说明注册中心和两个服务已经注册成功
需要注意的是为了演示负载均衡,启动spring-cloud-user-service时候启动两个服务8100和8200,启动命令如下:
java -jar spring-cloud-user-service-0.0.1-SNAPSHOT.jar --server.port=8100
java -jar spring-cloud-user-service-0.0.1-SNAPSHOT.jar --server.port=8200
2、服务调用
打开浏览器访问连续访问几次http://localhost:8082/consumer/getUser?id=1,我们可以看到每次处理请求的者user-service实例每次都是不一样的,这里就是客户端负载均衡策略的体现,我把调用过程做成了gif图片,效果如下:
到此SpringCloud通过Ribbon调用服务实现负载均衡的过程已经全部实现。