SpringCloud 之Ribbon客户端负载均衡


【spring cloud hoxton】Ribbon 真的能被 spring-cloud-loadbalancer 替代吗

Ribbon简介

官网地址:https://github.com/Netflix/ribbon
Ribbon进入维护状态了。 所以不建议使用了,替代方案是:Spring Cloud loadBalancer
在这里插入图片描述
在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于Http Restful的。SpringCloud有两种服务调用方式,一种是Ribbon+RestTemplate,另一种是Feign

Ribbon 是一个负载均衡客户端,可以很好的控制HTTP和TCP的一些行为。
Feign 默认集成了Ribbon。
Eureka Client 默认也集成了 Ribbon。
在这里插入图片描述
架构:
在这里插入图片描述
在这里插入图片描述
总结: Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例。

负载均衡

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

快速入门

创建一个model工程作为服务消费者,即eureka-ribbon-client
导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 该依赖是可以省略的,因为spring-cloud-starter-netflix-eureka-client中已经包含了spring-cloud-starter-netflix-ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

向程序的IOC注入一个Bean:RestTemplate;并通过@LoadBalanced注解表明这个RestTemplate开启负载均衡的功能。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class EurekaRibbonClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaRibbonClientApplication.class, args);
	}

    @Bean
    // 开启负载均衡功能
    @LoadBalanced
    public RestTemplate restTemplate(){
	    return new RestTemplate();
    }

}

配置文件appication.yml

server:
  port: 8082

spring:
  application:
    name: eureka-ribbon-client

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8100/eureka/

编写控制器,通过之前注入到IOC容器的RestTemplate来消费服务注册中心的服务,在这里直接用服务名替代了具体的URL地址,在Ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的URL替换掉服务名。

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;
import org.springframework.web.client.RestTemplate;

@RestController
public class DemoController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/ribbon")
    public String demo() {
        return restTemplate.getForObject("http://eureka-client/hello", String.class);
    }
}

启动测试
将同一个将要被消费的服务注册多个实例到注册中心。
分别启动注册中心,被消费的服务和当前的Ribbon服务。
在浏览器上多次访问http://127.0.0.1:8082/ribbon,浏览器交替显示:

hello port:8091
hello port:8081

Ribbon源码分析

Ribbon 的 负载均衡主要是通过 LoadBalancerClient 来实现的。
根据IRule 的实现类策略进行负载均衡,默认是:RoundRobinRule即轮询。
在这里插入图片描述
设置访问某个服务的具体策略:

serviceId.ribbon.NFLoadBalancerRuleClassName=自定义的负载均衡策略类
# eureka-client是服务ID
eureka-client:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

负载均衡策略:
接口:com.netflix.loadbalancer.IRule,其实现类:
在这里插入图片描述
RoundRobinRule:轮询
RandomRule:随机

在 RestTemplate 加上@LoadBalance 注解后,RestTemplate 对象添加了拦
截器org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor。在拦截器的方法中 ,将远程调度方法交给了 Ribbon 的 负载均衡器org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient去处理,然后通过serverId查找服务地址,通过一定的负载均衡策略去做真正的请求,从而达到了负载均衡的目的。

拦截器断点:
在这里插入图片描述
Ribbon负载均衡客户端断点:
在这里插入图片描述

LoadBalancerClient 实现负载均衡的简单原理

LoadBalancerClientSpringCloud提供的负载均衡器客户端抽象接口

LoadBalancerClient先从提供的服务中获取某一个实例(默认策略为轮询),比如订单服务需要访问商品服务,商品服务有3个节点,LoadBalancerClient会通过choose(),方法获取到3个节点中的一个服务,拿到服务的信息之后取出服务ip信息,就可以得到完成的想要访问的ip地址和接口,最后通过RestTempate访问商品服务。

SpringCloud提供的组件Ribbon,内部实现了LoadBalancerClient接口,实现类RibbonLoadBalancerClient,通过@LoadBalance注解开启负载均衡器。
Spring Cloud loadBalancer内部的实现类是:BlockingLoadBalancerClient

解析LoadBalancerClient接口源码:
在这里插入图片描述
LoadBalancerClient接口继承了ServiceInstanceChooser接口,主要的方法为2个execute方法,均是用来执行请求的,还有个reconstructURI()是用来重构URL的。

进入ServiceInstanceChooser接口中,可以看到主要的方法为choose(),用来根据服务的名称,获取来选择其中一个服务实例,也就是根据seriverId获取ServiceInstance
在这里插入图片描述

解析LoadBalancerClient接口实现类RibbonLoadBalancerClient:
RibbonLoadBalancerClient实现了服务的负载和选择,以及负载策略的配置,整个的负载均衡都由它实现。

  • choose(),用来选择具体的服务实例。
  • getServer(),获取实例。
  • 最终通过ILoadBalancer去做服务选择实例。
    在这里插入图片描述
    进入 ILoadBalancer 实现类BaseLoadBalancer看下:
    在这里插入图片描述
    从上面我们看到ILoadBalancer中的chooseServer方法里面默认值为:default
    在这里插入图片描述
    可以看到这个ruleIRule接口声明出来的,且默认定义的实现类是RoundRobinRule,也就是轮询策略。

IRule接口定义了3个方法,choose是用来选择实例的,setLoadBalancer和getLoadBalance用来设置和获取ILoadBalancer的。
在这里插入图片描述
下面是IRule接口的所有实现类:
在这里插入图片描述
通过IRule接口实现来设置负载策略:
在这里插入图片描述
总结:
1、LoadBalancerClient——>RibbonLoadBalancerClient中的choose()
首先需要传一个serverId,也就是服务id,通过LoadBalancerClient接口调用实现类RibbonLoadBalancerClient中的 choose(serverid) 方法。
在这里插入图片描述
2、choose()---->getServer(ILoadBalancer loadbalance)----->chooseServer()
choose(serverid)内部调用getServer(ILoadBalancer loadBalancer, Object hint),getServer方法通过ILoadBalancer类进行了负载策均衡之旅。
在这里插入图片描述
3、实现chooseServer()方法
接着通过实现ILoaddBalancer接口的chooseServer(Object key)方法,实现类为BaseLoadBalancer
在这里插入图片描述
4、过IRule接口,自定义负载策略。
其实LoadBalancerClient 还有个核心类IPing,这里就不多解析了,向EurekaClient获取注册列表信息,默认每10秒向EurekaClient发送一次ping,进而检查是否需要更新服务的注册列表信息。
负载均衡的实现LoadBalancerClient具体交给了ILoadBalancer来处理,ILoadBalancer通过配置IRule、IPing等,向EurekaClient获取注册列表信息,默认每10秒向EurekaClient发送一次ping,进而检查是否需要更新服务的注册列表信息。最后,在得到服务注册列表信息后,ILoadBalancer根据IRule的策略进行负载均衡。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值