不怕难之Spring Cloud系列之Ribbon

2019-07-18  本文已影响0人  天外流星for

一、引言

讲解Ribbon之前,先提4个问题,作为引子

1.  什么是负载均衡, 为什么要有负载均衡?

2.  你所知道的负载均衡有哪些?

3. 负载均衡主要体现在CAP中的哪些?

4.   如果让你设计一个负载均衡,需要考虑哪些点?

二、Ribbon出现的时机

1. 服务器端负载均衡器

传统上,Load Balancers是放置在服务器端的组件。当请求来自 客户端 时,它们将转到负载均衡器,负载均衡器将为请求指定 服务器。负载均衡器使用的最简单的算法是随机指定。在这种情况下,大多数负载平衡器是用于控制负载平衡的硬件集成软件。

重点:

对客户端不透明,客户端不知道服务器端的服务列表,甚至不知道自己发送请求的目标地址存在负载均衡器。

服务器端维护负载均衡服务器,控制负载均衡策略和算法。

2.  客户端负载均衡器

当负载均衡器位于 客户端 时,客户端得到可用的服务器列表然后按照特定的负载均衡策略,分发请求到不同的 服务器 。

重点:

对客户端透明,客户端需要知道服务器端的服务列表,需要自行决定请求要发送的目标地址。

客户端维护负载均衡服务器,控制负载均衡策略和算法。

目前单独提供的客户端实现比较少,大部分都是在框架内部自行实现。

三、Ribbon 介绍

Ribbon是Netflix公司开源的一个客户单负载均衡的项目,可以自动与 Eureka 进行交互。它提供下列特性:

负载均衡

容错

以异步和反应式模型执行多协议 (HTTP, TCP, UDP)

缓存和批量

Ribbon中的关键组件

四、Ribbon使用

1.在启动类中,声明一个RestTemplate的bean,用@LoadBalanced注解修饰:

@Bean

@LoadBalanced

public RestTemplate restTemplate() {

    return new RestTemplate();

}

2. 在进行http调用的地方,通过@Autowired方式,注入RestTemplate,再通过restTemplate调用。调用时,写服务名就可以,比如按照下面这种方式调用。

return this.restTemplate.getForEntity("http://MICROSERVICE-PROVIDER/provider", String.class).getBody();

五、Spring Cloud Ribbon源码分析

由于源码分析一般比较枯燥,采用一种新的方式。如果有你来设计一套负载均衡,你会考虑哪些点。   一问一答的形式来层层解析

1.  如何引入负载均衡

重点: 使用负载均衡的开发量还是挺简单的,不过为什么在restTemplate上加个注解,通过restTemplate进行调用,就可以做到负载均衡呢,这里就需要研究下源码才能知道原因了。

2. 如何对请求进行拦截

重点:

注释中说明这个类是为Ribbon做自动配置的,类上的@Configuration说明这是一个配置类,在当前项目中存在RestTemplate类、并且存在LoadBalancerClient接口的实现类时,就满足了自动化配置的条件。

在LoadBalancerAutoConfiguration类中,创建了一个LoadBalancerInterceptor拦截器,还维护了一个被@LoadBalanced修饰的RestTemplate列表,在初始化的时候,会为每个restTemplate实例添加LoadBalancerInterceptor拦截器。

3. 如何对请求的服务进行解析

重点:

由于在自动配置类中,对restTemplate实例添加了LoadBalancerInterceptor拦截器,所以,当用restTemplate发送http请求时,就会执行这个拦截器的intercept方法。

intercept方法中,会根据request.getURI(),获取请求的uri,再获取host,我们在发送http请求的时候,是用的服务名作为host,所以,这里就会拿到服务名,再调用具体LoadBalancerClient实例的execute方法,发送请求。

4.  如何从注册中心获取服务列表

重点:

在这个方法中,就是通过eurekaClient去注册中心获取服务,将状态为up的服务实例封装成DiscoveryEnabledServer对象,然后放入列表返回,这就是获取服务列表的流程

5.  如何选择最匹配的服务

重点:

这个方法会根据server的zone和可用性来选择具体的实例,返回一个Server对象。需要理解zone的概念

6.  如何调用远程的服务

重点:

LoadBalancerClient的实现类为RibbonLoadBalancerClient,最终的负载均衡请求由它来执行。从一系列服务中,根据选择的服务,远程调用。比较经典的有http请求,ribbon封装的请求

7.  客户端如何维护服务列表

重点:

里面有个start方法,实现了Runnable接口,run方法里调用UpdateAction的doUpdate,之后再启动一个定时任务,执行这个方法。定时任务传入的两个时间参数:initialDelayMs和refreshIntervalMs,任务启动后一秒开始执行,并且每隔三十秒执行一次,用于刷新列表。构造DynamicServerListLoadBalancer实例的时候,就会启动一个定时任务了,一开始先获取服务列表,之后每隔三十秒获取一次。负载均衡时,就是通过负载均衡算法在实例列表中选择一个,发送请求。

六、 Spring Cloud Ribbon处理流程

七、Spring Cloud Ribbon源码跟踪图

八、小结

            1.  分析了Spring Cloud Ribbon的核心处理源码-------功能强大

            2.  跟踪了Spring Cloud Ribbon的处理流程主线-------架构优雅

            3.   启发了如何自己来设计一套负载均衡中间件------- 流程清晰

上一篇 下一篇

猜你喜欢

热点阅读