负载均衡 Ribbon 与 Fegin 远程调用原理
文章目录
- 一、什么是负载均衡
- 二、Ribbon 负载均衡
- 2.1 Ribbon 使用
- 2.2 Ribbon 实现原理 (★)
- 2.3 Ribbon 负载均衡算法
- 三、Feign 远程调用
- 3.1 Feign 简述
- 3.2 Feign 的集成
- 3.3 Feign 实现原理 (★)
一、什么是负载均衡
《服务治理:Nacos 注册中心》 末尾提到了负载均衡,那什么是负载均衡呢?
负载均衡就是将负载(⼯作任务,访问请求)进⾏分摊到多个操作单元(服务器,组件)上进行执行。
根据负载均衡发⽣位置的不同,⼀般分为: 服务端负载均衡 和 客户端负载均衡。
- 服务端负载均衡指的是发生在服务提供者一方,比如常见的 Nginx 负载均衡。
- 客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求。

注:在微服务调⽤关系中⼀般会选择客户端负载均衡,也就是在服务调用的一方来决定服务由哪个提供者执行。
二、Ribbon 负载均衡
2.1 Ribbon 使用
Ribbon 是 Spring Cloud 的⼀个组件, 它可以让我们使用一个注解就能轻松的搞定负载均衡。
1、在 RestTemplate 的生成方法上添加 @LoadBalanced 注解
@Bean
@LoadBalanced // 表示继承Ribbon进行负载均衡
public RestTemplate restTemplate() {return new RestTemplate();
}
2、修改服务调用的方法
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderDao orderDao;@Autowiredprivate RestTemplate restTemplate;@Overridepublic Order createOrder(Long productId, Long userId) {log.info("接收到{}号商品的下单请求,接下来调⽤商品微服务查询此商品信息", productId);// 远程调⽤商品微服务,查询商品信息String url = "http://product-service/product/" + productId;log.info("服务器地址: {}", url);// 远程调⽤商品微服务,查询商品信息Product product = restTemplate.getForObject(url, Product.class);log.info("查询到{}号商品的信息,内容是:{}", productId, JSON.toJSONString(product));// 创建订单并保存Order order = new Order();order.setUid(userId);order.setUsername("安秀岩");order.setPid(productId);order.setName(product.getName());order.setPrice(product.getPrice());order.setNumber(1);orderDao.save(order);log.info("创建订单成功,订单信息为{}", JSON.toJSONString(order));return order;}
}

对比以下两种方式,差异显著:
//⾃定义规则实现随机挑选服务List<ServiceInstance> instances = discoveryClient.getInstances("product-service");int index = new Random().nextInt(instances.size());ServiceInstance instance = instances.get(index);String url = instance.getHost() + ":" + instance.getPort();log.info("从nacos中获取到的微服务地址为:" + url);简化成了以下一行// Ribbon 直接使用需要远程调用的服务名称即可
String url = "http://product-service/";
那 Ribbon 底层原理又是什么呢?为什么可以使用服务名称就能远程调用该服务呢?
2.2 Ribbon 实现原理 (★)
现假设:两个商品服务做集群,向Nacos注册的IP分别是192.168.10.111:8081,192.168.10.112:8081
step1:当使用 RestTemplate 远程访问时,http://product-service/product/1 首先会将服务名称截取出来 product-service
step2:并在本地缓存列表中获取到服务的 IP 集合,即{{192.168.10.111:8081}, {192.168.10.112:8081}}。
step3:根据内部配置的 负载均衡算法,从集合中选取其中一个IP地址,如:192.168.10.112:8081
step4:将原来的 url 替换成 http://192.168.10.112:8081/product/1,最终通过 RestTemplate 发起请求。
2.3 Ribbon 负载均衡算法
Ribbon 内置了多种负载均衡策略,内部负载均衡的顶级接口为 com.netflix.loadbalancer.IRule,具体的负载策略如下图所示:

可以通过修改配置来调整 Ribbon 的负载均衡策略,如在 order-server 项目的 application.yml 中增加如下配置:
product-service: # 调⽤的提供者的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
三、Feign 远程调用
3.1 Feign 简述
为什么要使用 feign 呢?原来的调用的方式 String url = "http://product-service/product/" + productId; 是固定的字符串做拼接不够灵活,而且还存在 productId 参数校验问题等,因此 Feign 可解决这个问题。
Feign 是 Spring Cloud 提供的⼀个声明式的伪 Http 客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。Nacos 很好的兼容了 Feign,Feign 默认集成了 Ribbon,所以在 Nacos 下使用 Fegin 默认就实现了负载均衡的效果。
3.2 Feign 的集成
1、在shop-order-server项⽬的pom文件加入Fegin的依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、在启动类上添加 Fegin 的扫描注解 @EnableFeignClients,注意扫描路径(默认扫描当前包及其子包)
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 会扫描当包及其子包下贴有@FeignClient注解的接口
public class OrderServer {public static void main(String[] args) {SpringApplication.run(ProductApplication .class, args);}
}
3、在 shop-order-server 项目中新增接口 ProductFeignApi 和该接口的容错类 ProductFeignFallback
@FeignClient(name = "product-service", fallback = ProductFeignFallback.class)
// 远程调用服务名称;fallback 指定返回兜底数据的类的字节码,即服务挂起时的降级类方法
public interface ProductFeignApi {@RequestMapping("/product/{pid}")// 路径要与 ProductController 的接口保持一致Product findByPid(@PathVariable("pid") Long pid);
}
@Component // 该类的作用是返回兜底数据以防 “服务器雪崩”
public class ProductFeignFallback implements ProductFeignApi {@Overridepublic Product findByPid(Long pid) {System.out.println("返回兜底数据");return new Product();}
}

4、修改服务调用的方法
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderDao orderDao;@Autowiredprivate ProductFeignApi productFeignApi;@Overridepublic Order createOrderFeign(Long productId, Long userId) {// feign 调用Product product = productFeignApi.findByPid(productId);log.info("查询到{}号商品的信息,内容是:{}", productId, JSON.toJSONString(product));// 创建订单并保存Order order = new Order();order.setUid(userId);order.setUsername("叩丁狼教育");order.setPid(productId);order.setName(product.getName());order.setPrice(product.getPrice());order.setNumber(1);orderDao.save(order);log.info("创建订单成功,订单信息为{}", JSON.toJSONString(order));return order;}
}
3.3 Feign 实现原理 (★)
Feign 实现的原理是基于动态代理和反射技术,并且内部还是使用 RestTemplate 实现的,具体详细流程如下:

文章参考:Java微服务商城高并发秒杀项目实战|Spring Cloud Alibaba真实项目实战+商城双11秒杀+高并发+消息+支付+分布式事物Seata
相关文章:
负载均衡 Ribbon 与 Fegin 远程调用原理
文章目录 一、什么是负载均衡二、Ribbon 负载均衡2.1 Ribbon 使用2.2 Ribbon 实现原理 (★)2.3 Ribbon 负载均衡算法 三、Feign 远程调用3.1 Feign 简述3.2 Feign 的集成3.3 Feign 实现原理 (★) 一、什么是负载均衡 《服务治理:Nacos 注册中心》 末尾提到了负载均…...
c/c++:CMakeLists.txt中添加编译/连接选项使用内存错误检测工具Address Sanitizer(ASan)
Address Sanitizer(ASan)是一个快速的内存错误检测工具。从gcc 4.8开始,AddressSanitizer成为gcc的一部分。 既然是gcc内置的内存检查工具,用起来比第三方的库更方便些。只要指定相应的编译链接参数就可以实现内存泄露检查了,如下是是cmake脚…...
armbian cups 远程打印机 1022
使用 CUPS Web 浏览器界面设置和管理打印机 - Oracle Solaris 管理:常见任务 N1刷armbian变身打印服务器,支持全平台无线打印PC扫描_存储设备_什么值得买 (smzdm.com) 第 6 章 使用 Web 界面向 CUPS 添加打印机 | Red Hat Product Documentation apt…...
three.js使用3DTilesRendererJS加载3d tiles数据
原生的 three.js 目前不支持 3d tiles 数据的加载,不过开源社区已经给出了一些解决方案,其中最活跃的要属 3DTilesRendererJS。它为 three.js 提供了加载和调度 3d tiles 数据的基本能力,虽说和 Cesium.js 对 3d tiles 的支持相比还有很大的差…...
坐牢第三十五天(c++)
一.作业 1.使用模版类自定义栈 代码: #include <iostream> using namespace std; template<typename T> // 封装一个栈 class stcak { private:T *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参…...
Conda离线部署django
要在没有网络连接的环境中使用conda部署Django,你需要预先在有网络连接的机器上创建一个包含所有必要包的环境,并导出该环境的配置文件。然后,你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤: 1. …...
1. Fabric.js安装使用
安装 # 安装 fabricjs npm i fabric --save在需要使用的页面引入 import * as fabric from fabric...
Excel中.xls和.xlsx文件格式的区别,及C++操作Excel文件
文件结构和兼容性: XLS是Excel 97-2003版本的文件格式,而XLSX是Excel 2007及以上版本的文件格式。XLS格式是向下兼容的,意味着较新的Excel版本可以打开XLS文件,但较旧的版本无法打开XLSX文件。相反,XLSX格式是向上…...
php实用命令
php相关命令 命令错误级别 命令 命令命令介绍具体用法php -v查看php版本php -vphp -l检查php文件是否有语法错误php -lphp -m查看当前php安装的扩展php -mphp -i | grep extension_dir查看扩展安装的目录php -i | grep extension_dir 错误级别 命令命令介绍具体用法error_re…...
TypeError:未绑定方法
TypeError: unbound method 错误通常发生在类方法被调用时,但没有正确绑定到实例。这通常意味着你试图在类本身上调用一个实例方法,或者没有使用正确的方式创建类实例。 1、问题背景 某位开发者在尝试创建一个类似于经典的 Pratt 递归下降解析器时遇到了…...
Java虚拟机(JVM)的架构和工作原理,字节码执行流程
JVM的概念 JVM是Java Virtual Machine的缩写, 即Java虚拟机,也被称为Java程序运行的核心环境 。它是一种用于计算设备的规范,通过在实际的计算机上仿真模拟各种计算机功能来实现。JVM由一套字节码指令集、一组寄存器、一个栈、一个…...
416.分割等和子集
416.分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和…...
python初始化一个三维数组
文章目录 1.什么是三维数组2.那我应该如何初始化一个自定义长度的三维数组呢? 1.什么是三维数组 从最外层开始理解,可以理解为一维数组,里面套了一个二维数组(12等于三维数组) arr [ [[], []], [[], [], []], [[],[]]…...
EI会议推荐-第二届大数据与数据挖掘国际会议(BDDM 2024)
第二届大数据与数据挖掘国际会议(BDDM 2024) 1、基本信息 大会官网:http://www.icbddm.org/ 官方邮箱:icbddm163.com 主办方:武汉纺织大学 会议时间:2024年12月13日-12月15日 会议地点:湖…...
RK3566/RK3568 Android 11 动态显示/隐藏下拉框
概述 在系统服务中增加显示/隐藏状态栏方法,在上层app动态调用显示/隐藏下拉框方法,设备关机和重启后也能继续生效。 创建全局变量 1.定义全局变量 在frameworks/base/core/java/android/provider/Settings.java中添加 /*** Disable drop-down box* @hide*/public static…...
Android图片缓存工具类LruCache原理和使用介绍
LruCache & DiskLruCache原理。 常用的三级缓存主要有LruCache、DiskLruCache、网络,其中LruCache对应内存缓存、 DiskLruCache对应持久化缓存。Lru表示最近最少使用,意思是当缓存到达限制时候,优先淘汰近 期内最少使用的缓存,…...
生活杂记1
生命中,总有一些事需要你一生去治愈,我把这些杂记写出来,写完了就不再想了,太内耗了…hahaha~ 因为嘴馋,小时候经常去老姑家,她家有各类零食及平时很少吃的“山珍海味”。去的次数多了,就和她家…...
go常用代码
连接阿波罗: 默认properties类型 package mainimport ("fmt""github.com/apolloconfig/agollo/v4""github.com/apolloconfig/agollo/v4/env/config" )func main() {c : &config.AppConfig{AppID: "2222",Cl…...
各种各样的正则表达式
一、校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(0|[1-9][0-9]*)$ 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$ 正…...
WebRTC 基础
WebRTC 基础 目录 什么是 WebRTCWebRTC 的基本概念WebRTC 的基本流程 连接建立流程图 WebRTC 的基本对象 RTCPeerConnectionRTCSessionDescriptionRTCIceCandidate WebRTC API 详解 RTCPeerConnection API媒体流 API 详细的代码示例 基本连接示例完整的 WebRTC 实现示例 总结…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
手动给中文分词和 直接用神经网络RNN做有什么区别
手动分词和基于神经网络(如 RNN)的自动分词在原理、实现方式和效果上有显著差异,以下是核心对比: 1. 实现原理对比 对比维度手动分词(规则 / 词典驱动)神经网络 RNN 分词(数据驱动)…...
P10909 [蓝桥杯 2024 国 B] 立定跳远
# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上,小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时࿰…...
