RestTemplate
是 Spring Resources 中一个访问第三方 RESTful API 接口的网络请求框架。RestTemplate 的设计原则和其他 Spring Template(例如 JdbcTemplate、JmsTemplate)类似,都是为执行复杂任务提供了一个具有默认行为的简单方法。
RestTemplate 是用来消费 REST 服务的,所以 RestTemplate 的主要方法都与 REST 的 Http 协议的一些方法紧密相连,例如 HEAD、GET、POST、PUT、DELETE 和 OPTIONS 等方法,这些方法在 RestTemplate 类对应的方法为 headForHeaders()、getForObject()、postForObject()、put() 和 delete() 等。
举例说明,写一个 RestTestController 类,获取 https://www.baidu.com/ 的网页 Html 代码。首先在 RestTestController 类上加 @RestController 注解,开启 RestController 的功能。通过 RestTemplate 的 getForObject() 方法可以获取 https://www.baidu.com/ 的网页 Html 代码,并在 API 接口 /testRest 返回该网页的 Html 字符串。代码如下:
@RestController
public class RestTestController {
@GetMapping("/testRest")
public String testRest(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject("https://www.baidu.com/", String.class);
}
}
RestTemplate 支持常见的 Http 协议的请求方法,例如 Post、Put、Delete 等,所以用 RestTemplate 很容易构建 RESTful API。在上面的例子中,RestTemplate 用 Get 方法获取 https://www.baidu.com 网页的 Html 字符串。RestTemplate 的使用很简单,它支持 Xml、JSON 数据格式,默认实现了序列化,可以自动将 JOSN 字符串转换为实体。例如以下代码可以将返回的 JSON 字符串转换成一个 User 对象。
User user=restTemplate.getForObject("https://www.xxx.com/",User.class);
Ribbon 简介
负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。服务端负载均衡, 是独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如 Ngnix。另一种是客户端负载均衡, 是将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提供者的信息列表,有了信息列表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到负载均衡的目的。
Ribbon 是 Netflix 公司开源的一个负载均衡的组件,它属于上述的客户端负载均衡,是将负载均衡逻辑封装在客户端中,并且运行在客户端的进程里。Ribbon 是一个经过了云端测试的 IPC 库,可以很好地控制 HTTP 和 TCP 客户端的负载均衡行为。
在 Spring Cloud 构建的微服务系统中,Ribbon 作为服务消费者的负载均衡器,有两种使用方式,一种是和 RestTemplate 相结合,另一种是和 Feign 相结合。Feign 已经默认集成了 Ribbon,关于 Feign 的内容将会在下一章进行详细讲解。
Ribbon 有很多子模块,但很多模块没有用于生产环境,目前 Netflix 公司用于生产环境的 Ribbon 子模块如下:
- ribbon-loadbalancer:可以独立使用或与其他模块一起使用的负载均衡器 API。
- ribbon-eureka:Ribbon 结合 Eureka 客户端的 API,为负载均衡器提供动态服务注册列表信息。
- ribbon-core:Ribbon 的核心 API。
本节的实验会基于上一节 Eureka Server 实验代码的基础上进行改造。首先回顾一下上一节实验中的代码结构,它包括一个服务注册中心 eureka-server、一个服务提供者 eureka-client。eureka-client 向 eureka-server 注册服务,并且 eureka-client 提供了一个 /hi API 接口,用于提供服务。
首先修改 eureka-server 的 application.yml 文件,修改后的具体配置代码如下:
server:
port: 8080
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
然后修改 eureka-client 的 application.yml 文件,修改后的具体配置代码如下:
---
spring:
profiles: client01
application:
name: eureka-client
server:
port: 8762
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
---
spring:
profiles: client02
application:
name: eureka-client
server:
port: 8763
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
上述配置中,定义了两个 profile 文件,分别为 client01 和 client02,它们的端口号分别为 8762 和 8763,之后我们可以根据不同的 profile 来启动两个 eureka-client。
修改完 eureka-client 的配置文件之后,进入 eureka-client 根目录,通过 Maven 编译打包工程。
cd /home/project/eureka/eureka-client
mvn clean package -Dmaven.test.skip=true
通过 java -jar 的方式启动工程,并通过 spring.profiles.active 指定启动的配置文件,在本实验中需要启动两个 Eureka Client 实例。由于实验可能会启动很多个 Spring Boot 工程,为了防止内存溢出造成预料之外的后果,从本节实验开始,都通过使用 java -jar 的形式启动 Spring Boot 工程,这也是真实环境中所采用的方法。同时避免了开启多个控制台窗口。
首先在控制台中进入主 Maven 工程 eureka 的根目录,通过以下命令打包 eureka-server 和 eureka-client 模块。
cd /home/project/eureka
mvn clean package -Dmaven.test.skip=true
java -Xmx128m -jar ./eureka-server-0.0.1-SNAPSHOT.jar > server.log 2>&1 &
tail -n 20 -f server.log
Eureka Server 启动完成后,通过以下命令后台启动 Eureka Client。
java -Xmx128m -jar ./eureka-client-0.0.1-SNAPSHOT.jar --spring.profiles.active=client01 > client01.log 2>&1 &
java -Xmx128m -jar ./eureka-client-0.0.1-SNAPSHOT.jar --spring.profiles.active=client02 > client02.log 2>&1 &
Eureka Server 和两个 Eureka Client 都启动完成后,打开 Web 服务,可以在 Eureka Server 的首页看到两个 eureka-client 实例已经成功向服务注册中心注册,它们的端口分别为 8762 和 8763,如下图所示: