Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Ribbon讲解与应用

Ribbon讲解与应用

作者头像
后端码匠
发布于 2020-09-15 07:12:07
发布于 2020-09-15 07:12:07
52200
代码可运行
举报
文章被收录于专栏:后端码匠后端码匠
运行总次数:0
代码可运行

Ribbon [ˈrɪbən]

Ribbon是什么

  • Spring Cloud Ribbon是一个基于HTTP和TCP客户端 负载均衡 工具 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
  • 它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。
  • 面试造飞机, 工作拧螺丝

负载均衡-1.1

Ribbon能干嘛

  • LB(负载均衡 LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。
  • 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。
  • 常见的负载均衡有软件Nginx,LVS,硬件 F5等。
  • 相应的在中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
  • 负载均衡的简单分类
    • 集中式LB 即在服务的消费方和提供方之间使用独立的LB设施 (可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
    • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

注意:Ribbon就属于进程内LB ,它只是一个类库,集成于消费方进程,消费方通过它来 获取到服务提供方的地址

负载均衡-2.1

具体操作

pom

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.com.codingce</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-dept</artifactId>

    <dependencies>
        <!--我们需要拿到实体类, 所以要配置api -module-->
        <dependency>
            <groupId>cn.com.codingce</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Ribbon-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <!--Eureka  客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>
</project>

ConfigBean

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.codingce.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {   //configuration -- spring applicationContext.xml

    //配置负载均衡实现RestTemplate  @LoadBalanced
    //IRule
    //AvailabilityFilteringRule: 先会过滤掉, 跳闸, 访问故障服务器
    //RoundRobinRule    轮询
    //RandomRule    随机
    //RetryRule: 会按照轮询获取服务~ 如果服务获取失败, 则会在指定的时间内进行, 重试
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

DeptConsumerController

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.codingce.springcloud.controller;

import cn.com.codingce.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptConsumerController {

    // 理解消费者, 不应该有service层
    //RestFul风格
    //(url, 实体: Map classs<T> responseType)

    @Autowired
    private RestTemplate restTemplate;  //提供多种便捷访问远程http服务的方法

    //原 private static final String REST_URL_PREFIX = "http://localhost:8001";
    // Ribbon 我们这里是地址   因该是一个变量   通过服务来访问
    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";


    @RequestMapping("/consumer/dept/add")
    public boolean add(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
    }

    //http://localhost:8001/dept/list
    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class );
    }

    @RequestMapping("/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list" , List.class );
    }

}

自定义负载均衡

注意一点: 自定义类 单独拿出来 该类不能被@ComponentScan扫描到项目截图

自定义CodingCeRandomRule

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.codingce.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 该类不能被@ComponentScan扫描到
 * @author xzMa
 */
public class CodingCeRandomRule extends AbstractLoadBalancerRule {

    //自定义 每个服务, 访问5次, 换下一个服务(3个)

    //total = 0 默认=0 如果=5 我们指向下一个服务点

    private int total = 0;  //被调用的次数
    private int currentIndex = 0;   //当前是谁在提供服务


    public CodingCeRandomRule() {}

//    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;

            while(server == null) {
                //线程中断
                if (Thread.interrupted()) {
                    return null;
                }

                List<Server> upList = lb.getReachableServers(); //获得活着的服务
                List<Server> allList = lb.getAllServers();  //获得全部服务
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }


                //int index = this.chooseRandomInt(serverCount);  //生成区间随机数
                //server = (Server)upList.get(index); //从活着的服务, 随机获取一个

                //===================================================================
                if (total < 5) {
                    server = upList.get(currentIndex);
                    total++;
                } else {
                    total = 0;
                    currentIndex++;
                    //判断当前数量是否大于活着的数量
                    if(currentIndex > upList.size()) {
                        currentIndex = 0;
                    }
                    server = upList.get(currentIndex);  //从活着的服务中, 获取指定指定的服务进行操作
                }

                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    @Override
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}

CodingCeRule

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.codingce.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CodingCeRule {

    @Bean
    public IRule myRule() {
        return new CodingCeRandomRule();
        //默认是轮询 现在我们定义为 CodingCeRandomRule
        // 本次自定义   频繁操作 会出现 500 错误 继续自定义写RetryRule
    }

}

项目地址: https://github.com/xzMhehe/codingce-java

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端码匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Ribbon
SpringCloud-整合ribbon 1 在customer(服务消费方添加) <!-- Ribbon相关 (ribbon需要和eureka配合使用) --> <dependency>
用户5927264
2019/08/01
4920
Ribbon
【Spring Cloud】005-Ribbon负载均衡
Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具;
訾博ZiBo
2025/01/06
1550
【Spring Cloud】005-Ribbon负载均衡
SpringCloud学习笔记(2):使用Ribbon负载均衡
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以基于某种负载均衡算法,如轮询(默认)、随机、加权轮询、加权随机等自动帮助服务消费者调用接口。
布禾
2020/10/29
7090
SpringCloud学习笔记(2):使用Ribbon负载均衡
SpringCloud的入门学习之概念理解、Ribbon负载均衡入门
1、Ribbon负载均衡,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端、负载均衡的工具。
别先生
2019/12/02
4710
SpringCloud:spring-cloud-loadbalancer自定义负载均衡策略实现
网上的视频、博客基本都是使用spring-cloud-starter-netflix-ribbon这个依赖实现的,但springcloud在2020.0.0之后,移除掉了netflix-ribbon 使用eureka-client中的loadbalancer,使用自定义负载均衡不使用IRule接口,所以就遇到了很多问题,但这里也会复盘一下传统的实现!之后再讲新方法的实现,当然,也可以直接跳到二、使用LoadBalancer实现直接阅读新方法的使用
Freedom123
2024/03/29
1.4K0
SpringCloud:Eureka服务注册与发现
Eureka 其实就是一个 服务注册与发现的中心,也就是相当于我们前面做的一些生产者的服务需要注册到我们的注册中心,那么我们的消费者就不用把代码写死,而是可以去服务中心订阅对应的服务,获取服务的最新地址,并且进行逻辑解耦。
lwen
2018/07/23
8910
SpringCloud 连载(四) : Ribbon负载均衡与自定义算法(附视频)
上期内容我们讲了Cloud中非常重要的一个知识点Eureka服务注册与发现服务以及Eureka集群,有兴趣的同学可以从公众号中看一下。
不安分的猿人
2020/03/02
7100
Feign讲解与应用(文末送书)
Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。它让微服务之间调用变得更简单了, 类似controller调用service. SpringCloud集成了Ribbon Eureka, 可以在使用Feign时提供 负载均衡 的客户端
后端码匠
2020/10/27
8310
Feign讲解与应用(文末送书)
SpringCloud系列之客户端负载均衡Netflix Ribbon
负载均衡是一种基础的网络服务,它的核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力。提到负载均衡,你可能想到nginx。对于负载均衡,一般分为服务端负载均衡和客户端负载均衡
烂猪皮
2020/12/15
6490
09-SpringCloud Ribbon
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
彼岸舞
2021/08/24
3670
ribbon默认的负载均衡策略_集群负载均衡策略
官方文档指出:自定义的负载均衡配置类不能放在 @componentScan 所扫描的当前包下及其子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊化定制的目的了;
全栈程序员站长
2022/11/07
8360
Spring Cloud(三)负载均衡,服务熔断,服务降级,服务限流
整合依赖spring-cloud-starter-netflix-eureka-client里面也包含了ribbon的依赖
HcodeBlogger
2020/07/14
1.9K0
Spring Cloud(三)负载均衡,服务熔断,服务降级,服务限流
微服务(六)——Ribbon负载均衡服务调用
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
不愿意做鱼的小鲸鱼
2022/09/26
3400
微服务(六)——Ribbon负载均衡服务调用
Spring Cloud框架(原生Hoxton版本与Spring Cloud Alibaba)初级篇 ---- 服务调用
官方文档:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
百思不得小赵
2022/12/01
3060
Spring Cloud框架(原生Hoxton版本与Spring Cloud Alibaba)初级篇 ---- 服务调用
狂神说SpringCloud学习笔记[通俗易懂]
笔记整理来源 B站UP主狂神说https://www.bilibili.com/video/BV1jJ411S7xr
全栈程序员站长
2022/08/14
9000
狂神说SpringCloud学习笔记[通俗易懂]
Spring Cloud系列二:Ribbon
在微服务环境下每个服务实例少则几个,多则上百个,如何让请求均匀分布到各服务实例上是微服务架构下必须解决的一个问题,这方面有2种解决方案:
心平气和
2021/02/26
3770
springcloud3-服务到服务调用ribbon及openfeign
1,课程回顾 2,本章重点 ribbon (负载均衡器)如何实现服务到服务的调用 feign 服务到服务的调用 3,具体内容 3.1 ribbon 3.1.1 概念 Ribbon是一种客户端负载平衡器,可让您对HTTP和TCP客户端的行为进行大量控制(借助spring封装类RestTemplate,所有的入参,请求URL及出参数都是自己配置)。Feign已使用Ribbon,因此,如果使用@FeignClient,则本节也适用。 Ribbon中的中心概念是指定客户的概念。每个负载均衡器都是组件的一部分,这些组件可以一起工作以按需联系远程服务器,并且该组件具有您作为应用程序开发人员提供的名称(指定远程调用的服务名称,例如,使用@FeignClient批注)。根据需要,Spring Cloud通过使RibbonClientConfiguration为每个命名的客户端创建一个新的集合作为ApplicationContext。其中包含ILoadBalancer,RestClient和ServerListFilter。
张哥编程
2024/12/13
1260
springcloud3-服务到服务调用ribbon及openfeign
Ribbon与Spring cloud整合源码分析
Ribbon是一种客户端的负载均衡器。提供了多种负载均衡的算法,支持多种协议(HTTP,TCP,UDP),并提供了故障容错的能力。官方网址为:https://github.com/Netflix/ribbon。
良辰美景TT
2018/09/11
6360
Ribbon与Spring cloud整合源码分析
Ribbon实现客户端负载均衡
https://www.cnblogs.com/noneplus/p/11374883.html
Noneplus
2019/09/24
4060
Ribbon实现客户端负载均衡
Ribbon(客户端负载均衡)
server: port: 8001 servlet: context-path: /eureka-provider # 访问的项目名称在配置“集群”的时候也是必须一样的,否则不好调用 eureka: client: serviceUrl: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/,http://eureka7001.com:7001/eureka/ # eureka的暴露地址,直接注册,使用的是eureka的集群 instance: instance-id: eureka-provider:8001 ## instance-id区别服务 prefer-ip-address: true ## 访问路径可以显示服务主机的IP地址 spring: application: name: eureka-provider #微服务的名称,配置集群的时候必须相同
爱撒谎的男孩
2019/12/31
8700
推荐阅读
相关推荐
Ribbon
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验