RestTemplate简介

RestTemplate 是用来消费 REST 服务的,所以 RestTemplate 的主要方法都与 REST 的 H即 协议的一些方法紧密相连,例如 HEAD、 GET、 POST、 PUT、 DELETE 和 OPTIONS 等方法, 这些方法在 RestTemplate 类对应的方法为 headFor Headers()、 getForObject()、 postForObject()、 put()和 delete()等。 RestTemplate 支持常见的 Http 协议的请求方法,例如 Post、 Put、 Delete 等,所以用 RestTemplate 很容易构建 阻STful API。在上面的例子中 , RestTemplate 用 Get 方法获取, RestTemplate 的使用很简单,它支持 Xml、 JSON 数据格式,默认实现了序列化,可以自动将 JOSN 字符串转换为实体。例如以下代码可以将返 回的 JSON 字符申转换成一个 User 对象。

Ribbon简介

负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。 一种是独立进 程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如 Ngnix。另一种是将负载 均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提供 者的信息列表,有了信息列表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到负 载均衡的目的。

Ribbon 是 Netflix 公司开源的一个负载均衡的组件,它属于上述的第二种方式,是将负载 均衡逻辑封装在客户端中,并且运行在客户端的进程里。 Ribbon 是一个经过了云端测试的 IPC 库,司以很好地控制 HTTP 和 TCP 客户端的负载均衡行为。 在 Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器,有两种使用 方式,

一种是和 RestTemplate 相结合,另一种是和 Feign 相结合。Feign 已经默认集成了 Ribbon, 关于 Feign 的内容将会在下一章进行详细讲解。 阳bbon 有很多子模块,但很多模块没有用于生产环境,目前Netflix 公司用于生产环境的 Ribbon 子模块如下。 

ribbon-loadbalancer:可以独立使用或与其他模块一起使用的负载均衡器 API。

ribbon-eureka:阳bbon 结合 Eureka 客户端的 API,为负载均衡器提供动态服务注册列 表信息。 ribbon-core: Ribbon 的核心 API。

使用RestTemplate和Ribbon来消费服务

创建完成 eureka-ribbon-client 的 Module 工程之后, 在其 porn 文件中引入相关的依赖,包 括继承了主 Maven 工程的 porn 文件,引入了 Eureka Client 的起步依赖 spring-cloud-startereureka、Ribbon 的起步依赖spring-cloud-starter-ribbon,以及Web 的起步依赖spring-boot-starter- web

javaee的负载均衡 resttemplate负载均衡_客户端

 

 启动 eureka-server, 端口为 8761 。启动两个 eureka-client 实例,端口分别为 8762 和 8763。

在工程的配置文件 appIi ca ti on. yml 做程序的相关配置,包括指定程序名为 eureka-ribbonclient, 程序的端口号为 8764,服务的注册地址为 http://localhost:876l/eureka/

javaee的负载均衡 resttemplate负载均衡_javaee的负载均衡_02

 

 写一个RESTFUL API 接口,在该 API 接口内部需要调用 eureka-client 的 API 接口"/hi”, 即服务消费。由于 eureka-client 为两个实例,它们的端口为 8762 和 8763。在调用 eureka-client 的 API 接口“/hi”时希望做到轮流访问这两个实例,这时就需要将 RestTemplate 和 Ribbon 相 结合,进行负载均衡。 通过查阅官方文档,可以知道如何将它们结合在一起,只需要在程序的 IoC 容器中注入一个 restTemplate 的 Bean, 并在这个 Bean 上加上@LoadBalanced 注解,此时 RestTemplate 就结合了 阳bbon 开启了负载均衡功能,代码如下:

javaee的负载均衡 resttemplate负载均衡_负载均衡_03

 

 写一个阳bbonService 类,在该类的 hi()方法用 restTemplate 调用 eureka-client 的 API 接口 , 此时 Uri 上不需要使用硬编码(例如 IP 地址),只需要写服务名 eureka-client 即可,代码如下:

javaee的负载均衡 resttemplate负载均衡_javaee的负载均衡_04

 

 写一个 RibbonController 类,为该类加上@RestController 注解,开启 RestController 的功能, 写一个“/hi” Get 方法的接口,调用 RibbonService 类的 hi()方法,代码如下:

javaee的负载均衡 resttemplate负载均衡_负载均衡_05

 

 启动 eureka-ribbon-client 工程,在浏览器上访问 http://localhost:8761 , 显示的 Eureka Server 的主界面如图 6-2 所示 。 在主界面上发现有两个服务被注册 , 分别为 eureka-client 和 eureka-ribbon-client, 其中 eureka-client 有两个实例,端口为 8762 和8763 ,而 eureka-ribbon-client 的端口为 8764

在浏览器上多次访问 htφ://localhost:8764/hi?name=forezp,浏览器会轮流显示如下内容:


javaee的负载均衡 resttemplate负载均衡_API_06

 

 

loadBalancerClient简介

负载均衡器的核心类为 LoadBalancerClient, LoadBalancerCiient 可以获取负载均衡的服务提 供者的实例信息 。 为了演示,在 RibbonController 重新写一个接口“ /testRibbon ”,通过 LoadBalancerCI ient 去选择一个 eureka-client 的服务实例的信息, 并将该信息运囚,代码如下:

javaee的负载均衡 resttemplate负载均衡_客户端_07

 

  LoadBalancerClient 的 choose(”eureka-client'’)方法可以轮流得到 eureka-client 的两个 服务实例的信息。

那么负载均衡器是怎么获取到这些客户端的信息的呢?查看官方文档可以知道, 负载均衡 器 LoadBalancerClient 是从 Eureka Client 获取服务注册列表信息的,并将服务注册列表信息缓存 了一份。 在 LoadBalancerCJient 调用 choose()方法时,根据负载均衡策略选择一个服务实例的 信息,从而进行了负载均衡。 LoadBalancerClient 也可以不从 Eureka Client获取注册列表信息, 这时需要自己维护一份服务注册列表信息。
通过配置 ribbon.eureka.enable 为 false 来禁止调用 Eureka Client 获取注册列表。

在 Ribbon 中的负载均衡客户端为 LoadBalancerClient。在 Spring Cloud 项目中,负载均衡器 Ribbon 会默认从 Eureka Client 的服务注册列表中获取服务的信息,并缓 存一份。根据缓存的服务注册列表信息,可以通过 LoadBalancerClient 来选择不同的服务实例, 从而实现负载均衡。如果禁止 Ribbon 从 Eureka 获取注册列表信息,则需要自己去维护一份服 务注册列表信息。 根据自己维护服务注册列表的信息, Ribbon 也可以实现负载均衡。

维护服务注册列表信息通过 stores.ribbon.listOfServers 来配置这些服务实例的 Uri

javaee的负载均衡 resttemplate负载均衡_API_08

 


 LoadBalancerClient 是在初始化时向 Eureka 获取服务注册列表信息, 井且每 10 秒向 EurekaClient 发送“ping”,来判断服务的可用性。 如果服务的可用性发生了改变或者服务 数量和之前的不一致,则更新或者重新拉取。 LoadBalancerClient 有了这些服务注册列表信息, 就可以根据具体的 !Rule 的策略来进行负载均衡。

javaee的负载均衡 resttemplate负载均衡_javaee的负载均衡_09

 

 Ribbon 的负载均衡主要是通过 LoadBalancerClient 来实现的,而 LoadBalancerClient 具体交给了 ILoadBalancer 来处理, ILoadBalancer 通过配置 !Rule、 !Ping 等,向 EurekaClient 获取注册列表的信息,默认每 10 秒向 EurekaClient 发送一次“ping”, 进而检查是否需要更新 服务的注册列表信息。最后,在得到服务注册列表信息后, ILoadBalancer 根据!Rule 的策略进 行负载均衡。 而 RestTemplate 加上@LoadBalance 注解后,在远程调度时能够负载均衡, 主要是维护了 一个被@LoadBalance 注解的 RestTemplate 列表,并给该列表中的 RestTemplate 对象添加了拦 截器。在拦截器的方法中,将远程调度方法交给了 Ribbon 的负载均衡器 LoadBalancerClient 去处理,从而达到了负载均衡的目的。