SpringCloud学习笔记:负载均衡Ribbon(3)
1. RestTemplate简介
RestTemplate是Spring Resource中一个访问第三方RESTful API接口的网络请求框架。
RestTemplate是用来消费REST服务的,RestTemplate的主要方法与RESTHTTP协议紧密关联。
HTTP:HEAD、GET、POST、PUT、DELETE和OPTIONS等
RestTemplate:headForHeaders()、getForObject()、postForObject()、put()和delete()等
2. Ribbon简介
负载均衡是指将负载分摊到各个执行单元上。
常见的负载均衡有两种方式:
(1)独立进程单元:通过负载均衡策略,将请求转发到各个不同的执行单元上。如:Nginx;
(2)将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了服务提供者的信息列表。通过负载均衡策略将请求分摊给多个服务提供者,从而达到负载均衡的目的。
Ribbon是一个负载均衡组件,属于上述的第二种方式,将负载均衡逻辑封装在客户端中,并且运行在客户端的进程中。
在SpringCloud构建的微服务系统中,Ribbon作为服务消费者的负载均衡器,有两种使用方式:
(1)和RestTemplate相结合
(2)和Feign相结合
Feign默认集成了Ribbon。
Ribbon主要子模块:
◊ ribbon-core:ribbon项目核心,主要包括负载均衡器接口定义、客户端接口定义、内置发负载均衡实现等API;
◊ ribbon-eureka:为Eureka客户端提供负载均衡实现类;
◊ ribbon-httpclient:对Apache的HttpClient进行封装,提供包含负载均衡功能的REST客户端;
◊ ribbon-loadbalancer:独立使用或与其他模块一起使用负载均衡器API。
3. 使用RestTemplate和Ribbon消费服务
创建项目eureka-ribbon-client,通过RestTemplate来远程调用eureka-client服务API接口。
添加依赖spring-cloud-starter-ribbon
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>libing</groupId> <artifactId>eureka-ribbon-client</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>eureka-ribbon-client</name> <description>Demo project for Spring Boot</description> <parent> <groupId>libing</groupId> <artifactId>libing-eureka</artifactId> <version>1.0.0</version> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
RestTemplate结合Ribbon开启负载均衡:
package libing.eurekaribbonclient.common; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RibbonConfig { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
RibbonService使用restTemplate调用eureka-client的API接口:
package libing.eurekaribbonclient.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class RibbonService { @Autowired RestTemplate restTemplate; public String getPort() { return restTemplate.getForObject("http://eureka-client/helloworld", String.class); } }
package libing.eurekaribbonclient.controller; import libing.eurekaribbonclient.service.RibbonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("ribbon") public class RibbonController { @Autowired RibbonService ribbonService; @GetMapping public String getPort(){ return ribbonService.getPort(); } }
启动运行:
运行两个eureka-client实例
在浏览器中打开地址 http://localhost:8764/ribbon,交替显示:
port:8762
port:8763
4. LoadBalancerClient简介
负载均衡的核心类为LoadBalancerClient,LoadBalancerClient可以获取负载均衡的服务提供者的实例信息。
package libing.eurekaribbonclient.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("ribbon") public class RibbonController { @Autowired private LoadBalancerClient loadBalancer; @GetMapping public String getPort() { ServiceInstance instance = loadBalancer.choose("eureka-client"); return instance.getHost() + ":" + instance.getPort(); } }
LoadBalancerClient的choose("eureka-client")可以交替得到eureka-client的两个服务实例的信息。
负载均衡器LoadBalancerClient是从Eureka Client获取服务注册列表信息的,并将服务注册列表信息缓存一份。在LoadBalancerClient调用choose()方法时,根据负载均衡策略选择一个服务实例的信息,从而进行负载均衡。