微服务之Springcloud 从零基础到入门——Ribbon篇

微服务之Springcloud 从零基础到入门——Ribbon篇

一. Ribbon简介

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具。Ribbon虽然只是一个工具类框架,但它并不是需要独立部署的东西。像服务注册中心、配置中心、API网关都需要独立部署,但是Ribbon几乎存在于每一个微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,都是离不开负载均衡的。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

二. 负载均衡简介

负载均衡主要包含硬负载和软负载两个方面,硬负载一般是通过硬件来实现,比较常用的比如F5;软负载则主要通过在服务器上安装一些用于负载均衡功能或模块等软件来完成请求分发工作。软负载也主要分为服务端的负载均衡器和客户端的负载均衡器。Ngnix是具有代表性的一个服务端负载均衡器,而Ribbon是一个客户端软负载均衡器。

Ribbon实现负载均衡流程主要如图:
首先服务消费者会从注册中心找到相应的服务名称,然后Ribbon会根据一定的负载策略给消费者分配一个服务
Ribbon负载均衡

三. RestTemplate实现Ribbon

本实验已经在Eureka服务注册中心注册了两个相同的服务,其中服务器的搭建与服务提供者的创建可以参考我写的Eureka篇。

微服务之Springcloud 从零基础到入门——Eureka篇

注册的这两个服务的名称为CLOUD-PAYMENT-SERVICE
首先创建服务消费者,该服务消费者会去调用Eureka注册中心的服务。以下是创建服务消费者的流程。

  1. 引入依赖。因为Eureka已经默认集成了Ribbon,所以该处直接引入以下jar包。
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. 编写application.yml配置文件
server:
  port: 8601
spring:
  application:
    name: cloud-order-service    #注册到服务中心的名称
eureka:
  client:
    # 是否入驻进服务端
    register-with-eureka: true
    # 是否从server端抓取已有注册信息
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  1. 注入Restemplate模板到容器,在这边暂且基于RestTemplate实现服务调用,之后的笔记中会用到Openfeign。@LoadBalanced代表开启Ribbon的负载均衡策略,默认的策略为轮询算法。
@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced   //Ribbon的负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  1. 使用RestTemplate实现服务调用。如代码所示,相当于访问
    http://localhost:8601/consumer/payment/findById/{id}就是调用了http://CLOUD-PAYMENT-SERVICE/payment/findById/id。而此时CLOUD-PAYMENT-SERVICE包含了之前注册上去的两个服务,那么Ribbon会通过默认的负载策略给服务消费者分配其中的一个服务去提供服务。
@RestController
public class OrderController {
    public static final String URL="http://CLOUD-PAYMENT-SERVICE";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/findById/{id}")
    public CommonResult<Payment> findById(@PathVariable Long id){
        return restTemplate.getForObject(URL+"/payment/findById/"+id,CommonResult.class);
    }
}
四. Ribbon自带的负载均衡策略

首先Ribbon默认的负载策略为轮询算法,那么除了轮询算法Ribbon还包括以下几种负载策略。

策略类命名说明
RandomRule随机策略随机选择一个服务
RoundRobinRule轮询策略按顺序循环选择一个服务
RetryRule重试策略在一个配置时间段内选择服务不成功会一直尝试选择一个可用的服务
BestAvailabelRule最低并发策略忽略熔断器打开的服务,选择并发连接最低的服务
AvailibilityFilterRule可用过滤策略过滤掉一直链接失败和高并发连接的服务
ResponseTimeWeightedRule响应时间加权策略服务响应时间越短,权重越大,被选中提供服务的概率越高
ZoneAviodanceRule区域权衡策略综合服务所在区域性能和服务的可用性来轮询选择服务,会剔除不可用的服务
五. 改变Ribbon的负载均衡策略
  1. 通过配置类编写负载策略,在配置类中返回相应的Irule接口实现类,以下代码返回值为随机负载策略(注意:该MyRule类不能被Springboot主启动类扫描到,也就是至少在主启动类包的上一层包中)
@Configuration
public class MyRule {
    @Bean
    public IRule myrule(){
        return new RandomRule();
    }
}
  1. 修改主启动类,添加@RibbonClient注解,其中name是服务提供者的应用名称,configuration为MyRule配置类。可以理解为对该服务采用该负载算法
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRule.class)  //指定负载算法
public class Order8601Application {
    public static void main(String[] args) {
        SpringApplication.run(Order8601Application.class,args);
    }
}
六. 实现自己的负载均衡策略
  1. 编写自己的负载均衡器,该类实现了LoadBalance接口,主要代码如下,该代码用到了CAS原理,有不懂的读者请自行查找资料,该段代码的主要意思就是实现了一个轮询算法。(自己也写一个新的负载规则也没头绪,所以只能复写一个)
@Component
public class MyLoadBalance implements LoadBalance{

    private AtomicInteger atomicInteger=new AtomicInteger(0);

    public final int getAndIncrement(){
        int current;
        int next;
        do{
            current=atomicInteger.get();
            next=current+1;
        }while (!this.atomicInteger.compareAndSet(current,next));
        System.out.println("第"+next+"次访问");
        return next;
    }
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index=getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}
  1. 在controller中实现负载均衡
@RestController
public class OrderController {
    @Resource
    private RestTemplate restTemplate;
    @Resource    //引入自己写的负载均衡器
    private LoadBalance loadBalance;
    @Resource    //用于在注册中心找服务
    DiscoveryClient discoveryClient;
    @GetMapping(value = "consumer/payment/lb")
    public String myBalance(){
        //找到服务提供者的所有实例
        List<ServiceInstance> instances=discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if (instances ==null || instances.size()==0){
            return null;
        }
        //根据自己的负载均衡器得到相应的服务
        ServiceInstance instance=loadBalance.instances(instances);
        //得到其所在服务器的地址
        URI uri=instance.getUri();
        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }
}
七. 下一篇介绍

本文在使用服务消费者调用服务时采用的是RestTemplate,后续将对OpenFeign做介绍,来实现服务的调用。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值