SpringCloud Ribbon && OpenFeign

SpringCloud Ribbon && OpenFeign

SpringCloud Ribbon

Ribbon介绍

基本介绍

核⼼功能:Spring Cloud Ribbon是基于***flix Ribbon实现的⼀套客户端负载均衡⼯具,主要提供负载均衡算法和服务调⽤功能。
 实现原理:通过"负载均衡+RestTemplate调⽤"机制⼯作,在客户端本地缓存服务列表(默认30秒刷新),⾃动处理连接超时和重试机制。
 配置特性:提供完善的客户端配置项,包括连接超时、重试次数等容错机制,默认采⽤轮询算法进⾏服务调⽤。
实际应⽤:在会员中⼼等微服务场景中,Ribbon会从Eureka Server获取服务列表并在本地缓存,根据负载均衡算法选择服务实例(如10000或10002端⼝)。
 算法特点:默认轮询算法类似⽕⻋站售票窗⼝的分流机制,能均衡分配请求到性能相近的服务节点,是经过验证的合理⽅案

官网

https://github.***/***flix/ribbon

项目已进入维护状态, 在生产环境中仍在大规模使用, 替代方案为LoadBalancer

维护现状:***flix官⽅声明Ribbon进⼊维护模式,不再增加新功能,但核⼼组件仍在⽣产环境⼤规模使⽤。

LB(Load Balance)

1.负载均衡的分类
核⼼概念:负载均衡(Load Balance)是将⼯作负载分配到多个计算资源上的技术,在微服务架构中⽤于优化资源使⽤、最⼤化吞吐量、最⼩化响应时间。

1)集中式LB
定义:在服务消费⽅和提供⽅之间使⽤独⽴的LB设施进⾏请求转发
实现⽅式:
o 硬件实现:如F5等专⽤负载均衡设备
o 软件实现:如Nginx等反向代理服务器
⼯作流程:
o 客户端请求⾸先到达LB设施
o LB根据预设策略(轮询/随机/最⼩并发等)选择⽬标服务实例
o 请求被转发到选定的服务实例
特点:
o 作为独⽴中间层存在
o 对客户端透明,客户端⽆需知道后端服务细节
o 常⽤于⽹关层或⼊⼝流量分发

2)进程内LB
定义:将负载均衡逻辑集成到消费⽅进程中
典型代表:Spring Cloud Ribbon
⼯作流程:
o 消费⽅从服务注册中⼼(如Eureka)获取可⽤服务列表
o 在本地缓存服务实例信息
o 根据负载均衡策略直接选择⽬标实例进⾏调⽤
特点:
o 以类库形式集成在消费⽅进程内
o 消费⽅⾃主决定调⽤哪个服务实例
o 默认采⽤轮询算法(可替换)
o 需要配合服务发现组件使⽤
实际应⽤:如member-consumer轮询访问10000/10002端⼝的实现

2.两种LB的对⽐
架构差异:
o 集中式:独⽴中间层架构
o 进程内:客户端集成架构
 性能影响:
o 集中式可能成为单点瓶颈
o 进程内增加客户端复杂度但减少跳数
 适⽤场景:
o 集中式适合⼊⼝流量管理
o 进程内适合微服务间调⽤
 混合模式:实际系统中可能同时使⽤两种⽅式

Ribbon原理

ribbon机制和负载均衡算法

 核⼼组件:包含注册中⼼集群、服务健康监控、限流服务、负载均衡等多个模块
 系统架构:采⽤分布式微服务架构,通过⽹关统⼀管理服务调⽤和流量控制
 学习价值:理解该图可以提升系统架构思维,掌握分布式系统各组件协作关系

Ribbon架构图机制
 ⼯作流程:
o 注册阶段:服务提供者向Eureka Server注册实例
o 发现阶段:服务消费者从Eureka Server拉取可⽤服务列表
o 调⽤阶段:Ribbon根据负载算法选择具体服务实例进⾏调⽤
 缓存机制:
o 刷新间隔:默认每30秒从注册中⼼刷新⼀次服务列表
o 本地缓存:服务列表会缓存在JVM内存中,提⾼调⽤效率
o 动态感知:新增服务实例会⾃动加⼊轮询列表,⽆需重启消费者
 验证⽅法:可通过逐步启动服务提供者实例,观察负载均衡效果来验证机制

一、Ribbon 怎么从注册中心拿服务?
就像你去餐厅吃饭前会先看菜单,Ribbon 启动时会从 Eureka 服务器 “扒拉” 一份服务列表存在本地(比如美团商家的地址和状态),而且每隔一段时间会自动更新,保证列表是最新的。这样调用服务时就不用每次都问服务器,速度更快。
二、Ribbon 怎么挑服务?5 种常见 “挑人” 策略,用大白话讲清楚:

  1. “谁最闲选谁”(BestAvailableRule)

    先把 “生病” 的机器(比如经常出错的服务器)排除掉,然后在剩下的机器里,挑当前正在处理请求最少的那个。就像外卖小哥接单,优先派给手里订单最少的人。

  2. “过滤掉坑货”(AvailabilityFilteringRule)

    分两步挑:第一步排除 “连不上” 的机器(比如服务器死机了),第二步排除 “太忙” 的机器(比如同时接了 100 个请求的服务器)。就像点奶茶时,先排除关门的店,再排除排队太长的店。

  3. “看速度给权重”(WeightedResponseTimeRule)

    给每个机器打 “分”:响应速度快的机器(比如 1 秒内就返回结果)多派单,响应慢的(比如 5 秒才返回)少派单。就像快递站分配任务,手脚麻利的快递员多派件,磨叽的少派。

  4. “不行就再试一次”(RetryRule)

    如果第一次调用机器没反应,会在短时间内(比如 5 秒)反复试几次,直到成功或者试够次数为止。就像打电话给朋友,一次没接就再打几个,直到接通或放弃。

  5. “轮流干活”(RoundRobinRule)

    这是默认策略,就像排队买票,第一个请求给 A 机器,第二个给 B 机器,第三个给 C 机器,循环下去。适合所有机器性能差不多的情况。

  6. “随机抓阄”(RandomRule)

    完全随机选一个机器,就像抽奖一样。长期来看,每个机器被选中的次数差不多,适合没特殊要求的场景。

  7. “看地区挑最优”(ZoneAvoidanceRule)

    综合考虑机器所在的 “区域”(比如北京机房、上海机房)和可用性,优先选又近又不忙的机器。就像点外卖时优先选同小区或附近商圈的店,配送快还不容易超时。

三、选哪个策略最合适?
没特殊要求:直接用默认的 “轮流干活”(RoundRobinRule),简单公平。
机器性能差别大:用 “看速度给权重”(WeightedResponseTimeRule),让快的机器多干活。
怕服务超时:用 “不行就再试一次”(RetryRule),失败了多试几次,提高成功率。

Ribbon 确实是客户端进程内的负载均衡组件,可以理解为 “长在服务调用方代码里的调度员”。
为啥说它是 “进程内” 的?
举个例子:比如你有一个订单服务(A)要调用用户服务(B),Ribbon 不是独立的第三方服务,而是直接集成在订单服务 A 的代码里。当 A 要调用 B 时,Ribbon 就在 A 的进程内部直接处理负载均衡逻辑,比如从本地缓存的服务列表里挑一个 B 的实例,然后发起调用。
和 “进程外” 负载均衡的区别?

进程外(比如 Nginx):请求先经过 Nginx 这样的中间代理,由 Nginx 负责转发到不同的服务实例,相当于 “中间商赚差价”。
进程内(Ribbon):服务调用方自己就能决定调哪个实例,不需要经过中间代理,效率更高,也更灵活(比如可以针对不同服务定制不同策略)。

Ribbon 和 Eureka 怎么配合?

Eureka 负责 “记名单”:各个服务启动时向 Eureka 注册自己的地址和状态(比如用户服务 B 有 3 个实例:192.168.1.1:8080、192.168.1.2:8080 等)。
Ribbon 负责 “挑名单”:订单服务 A 启动时,从 Eureka 拉取用户服务 B 的所有实例列表,存在本地内存里。当 A 要调用 B 时,Ribbon 直接从本地列表里按规则选一个实例调用,不用每次都问 Eureka,速度更快。
动态更新名单:如果用户服务 B 的某个实例挂了,Eureka 会感知到并通知 Ribbon(或者 Ribbon 自己定期检查),Ribbon 就会把这个挂掉的实例从本地列表里 “划掉”,避免调错地方。

简单来说:
Ribbon 就像是服务调用方的 “私人助理”,坐在调用方的 “办公室”(进程)里,手里拿着 Eureka 给的 “通讯录”(服务列表),当调用方需要找某个服务时,助理直接按规则挑一个合适的联系方式(实例地址),让调用方直接沟通,省去了找中间人的麻烦。

切换负载均衡算法

#### 需求 默认算法修改:将Ribbon默认的轮询负载均衡算法改为随机算法RandomRule 访问⽅式:通过浏览器输⼊http://localhost/member/consumer/get/1进⾏访问 随机访问要求:要求访问的10000/10002端⼝的服务是随机的 Ribbon状态:⽬前处于维护状态 底层实现:Spring Cloud的负载均衡(Load Balance)底层就是基于Ribbon实现 默认算法:默认采⽤轮询负载均衡算法

启动顺序:
先启动Eureka Server集群(9001和9002端⼝)
启动服务提供⽅(10000和10002端⼝)
最后启动服务消费⽅(80端⼝)
分布式部署:这些服务可以部署在不同主机上形成分布式系统

替换⽬标:将轮询算法改为随机算法
预期效果:
刷新时可能连续多次调⽤同⼀端⼝服务
访问分布不再严格交替
实现⽅式:通过配置Ribbon的负载均衡规则来实现

访问⽅式:通过浏览器输⼊http://localhost/member/consumer/selectById/1进⾏访问

实现

1.创建RibbonRule
⽬的: 配置⾃定义的负载均衡算法。
实现⽅式: 创建⼀个名为RibbonRule的Java类,并使⽤@Configuration注解将其标识为配置类。
配置类作⽤: ⽤于配置和注⼊⾃定义的负载均衡算法。
关键⽅法: 在RibbonRule类中定义⼀个返回IRule接⼝实现类的⽅法,并使⽤@Bean注解将其注⼊Spring容器。
算法选择: 可以选择多种负载均衡算法,如RandomRule(随机选择)、RoundRobinRule(轮询)等。
实现⽅式:在RibbonRule类的⽅法中,通过return new RandomRule();等⽅式返回所选算法的对象实例。

@Configuration
public class RibbonRule {
    //配置和注⼊⾃定义的负载均衡算法
    //可以选择多种负载均衡算法,如RandomRule(随机选择)、RoundRobinRule(轮询)等。
    //
    @Bean
    public IRule getRibbonRule() {
        return new RandomRule();
    }
}

2.指定Ribbon的负载均衡算法
指定⽅式: 使⽤@RibbonClient注解在主启动类上,指定Ribbon客户端的名称和配置
参数说明:
name: Ribbon客户端的名称,对应服务提供者的名称。
configuration: ⾃定义的负载均衡配置类,即RibbonRule.class

@RibbonClient(name = "member-service-provider", configuration = RibbonRule.class)
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class MemberConsumerApplication80 {
    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MemberConsumerApplication80.class, args);
    }
}

OpenFeign

什么是OpenFeign

大体流程:消费者 -> openfeign -> eureka查地址 -> ribbon选实例 -> 发起请求

1.Ribbon+RestTemplate要自己打电话订奶茶
自己查找商家电话(在Eureka那找地址),要自己拨号(调用RestTemplate发请求),选哪家店(Ribbon选实例),代码是

String mobile = 查通讯录("大杯奶茶店");
Result 奶茶 = 打电话(电话 + "/买奶茶?规格=大杯");

2.OpenFeign(用外卖 APP 订奶茶)
直接在 APP 里搜 “大杯奶茶店”,选 “大杯珍珠奶茶”,APP 自动帮你查地址、选分店、下单:

Result 奶茶 = 外卖菜单.buyMilkTea("大杯");

最后总结:OpenFeign 就是 “微服务外卖 APP”
你只需要列菜单(定义 Feign 接口)、点单(Controller 调用),其他像查地址、选分店、发请求全由 APP(OpenFeign 框架)搞定,比自己打电话订奶茶省心 100 倍!

现在讲的Feign默认指的都是OpenFeign。

需求

实现

配置文件编写->主启动类配置->注册测试->接口开发->Controller开发->注解启用

1.建立个新模块e-***merce-consumer-openfeign-80,避免与原来的消费服务造成混淆。

2.端口保持一致,pom一致,配置文件修改应用名。

3.引入OpenFeign场景启动器

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!--引入eureka client场景启动器starter-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-***flix-eureka-client</artifactId>
</dependency>

4.启动类MemberConsumerOpenFeignApplication80.java添加注解 @EnableFeignClients

4.创建接口
@FeignClient注解:用于标注一个接口是OpenFeign的客户端,value属性指定服务提供方的名称;
远程调用方式:可以在接口中定义远程调用的方法,包括HTTP请求方式(如GET)和URL路径
服务注册与发现:OpenFeign结合Eureka等服务注册与发现组件,可以根据服务名动态调用服务实例

“奶茶店"就相当于“MEMBER-SERVICE-PROVIDER”,好多服务实例都是”奶茶店“,当你点了杯奶茶(调用了该服务下的某个接口),那么底层的ribbon就会负载均衡去调用其中的服务实例。
你只需要指定某个服务下的某个接口。由ribbon完成负载均衡和URL替换。

只需要考虑“能点什么”,就像外卖APP的菜单列表。
@FeignClient“搜行业”,@GetMappping“选菜品”,参数是“甜度,冰量”

@FeignClient("奶茶店") //搜"奶茶店"这个商家
public interface 奶茶订单接口 {
	@GetMapping("/珍珠奶茶/大杯") //菜单里的"大杯珍珠奶茶"
	奶茶 下单(@PathVariable("甜度") String 甜度); //甜度是参数
}
@***ponent
@FeignClient(value = "member-service-provider")
public interface MemberFeignService {

    @GetMapping("/selectById")
    @ResponseBody
    public Result selectById(Integer id);

    @PostMapping("/insert")
    @ResponseBody
    public Result insert(@RequestBody Member member);
}

5.创建controller

点单服务,消费者点击下单,调用feign接口

@***ponent
public class 点单服务 {
    @Resource
    private 奶茶订单接口 外卖APP;  // 注入外卖APP
    
    public 奶茶 点奶茶() {
        奶茶 我的奶茶 = 外卖APP.下单("半糖");  // 点击“下单半糖大杯珍珠奶茶”
        return 奶茶;
    }
}
@RestController
public class MemberFeignController {

    @Resource
    private MemberFeignService memberFeignService;

    @GetMapping("/selectById/{id}")
    @ResponseBody
    public Result selectById(@PathVariable("id") Integer id) {
        return memberFeignService.selectById(id);
    }

    @PostMapping("/insert")
    @ResponseBody
    public Result insert(@RequestBody Member member) {
        return memberFeignService.insert(member);
    }
}

6.测试

OpenFeign日志配置

基本介绍

实现

1.创建src/main/java/***/zzw/springcloud/config/OpenFeignConfig.java

@Configuration
public class OpenFeignConfig {
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

2.修改配置文件

logging:
  level:
    ***.zzw.springcloud.service.MemberFeignService: debug

3.演示完成后需注销@Bean和yml配置,通过重启服务关闭⽇志输出.忘记关闭可能导致敏感信息泄露或性能损耗

OpenFeign调用超时

ribbon:
  # 单位毫秒
  ReadTimeout: 8000
  ConnectTimeout: 8000
转载请说明出处内容投诉
CSS教程网 » SpringCloud Ribbon &amp;&amp; OpenFeign

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买