Ribbon与Feign学习笔记
一、初识Ribbon:负载均衡界的"老司机" 🛣️
🎭 Ribbon是何方神圣?
Ribbon是Netflix家的"金牌调解员",专门在客户端搞负载均衡!这位老司机自带多种策略:轮询(雨露均沾)、随机(看心情点兵)、权重(按实力分配),堪称微服务界的"公平分配大师"。
Ribbon的内心OS:"别慌!我有轮询大法,雨露均沾;随机策略,全靠缘分;权重分配,实力说话!"
🔧 启动Ribbon?简单到离谱!
Nacos已内置Ribbon,无需额外启动器,直接开搞!只需两步走:
a. 在RestTemplate上贴个"魔法贴纸":@LoadBalanced
b. 注入它:@Bean public RestTemplate restTemplate() { return new RestTemplate(); }
小贴士:这个@LoadBalanced注解就像给RestTemplate装上了GPS导航,让它知道要去哪里找服务。
🔍 原理揭秘:三步走,服务不迷路!
a. 拦截器大显神通 :获取服务列表(比如List)
b. 算法选妃 :用负载均衡策略(比如轮询或随机)挑一个幸运儿
c. 变身术:把URL里的服务名(如http://ribbon-provider/...)换成真实IP和端口,发送请求!
技术深挖:Ribbon通过DynamicServerListLoadBalancer动态获取服务列表,再通过IRule接口实现各种负载均衡策略。
💻 调用服务?一行搞定!
String url = "http://ribbon-provider/provider/getUserById/1";
User user = restTemplate.getForObject(url, User.class);
对比说明:传统方式需要硬编码IP地址,现在只需要服务名,Ribbon自动帮你找到正确的服务实例。
🎨 想玩"随机玩法"?自定义策略!
在配置类里加个"豆":
@Bean
public IRule iRule() {
return new RandomRule(); // 开启"随机大乐透"模式!
}
策略大全:
- RoundRobinRule:轮询策略,像转盘一样公平
- RandomRule:随机策略,全靠运气
- WeightedResponseTimeRule:权重策略,实力说话
- BestAvailableRule:最优策略,挑最空闲的
二、邂逅Feign:声明式调用的"懒人神器" 🛋️
⚙️ 安装Feign:一键三连!
a. 在pom.xml加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
b. 主类贴"开关贴纸":@EnableFeignClients
幽默时刻:Feign的Slogan:"懒人福音!定义接口就完事,让框架替你打工!"
🏗️ 入门三步曲:搭桥、写接口、下单!
a. 搭桥(feign_interface模块):
-
pom.xml加Feign依赖和公共模块
-
写Feign接口:
@FeignClient("feign-provider")
@RequestMapping("/provider")
public interface UserFeign {
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable("id") Integer id);
}
b. 下单(feign_consumer模块):
-
引入feign_interface依赖
-
控制器注入Feign接口:
@Autowired
private UserFeign userFeign;public User getUser(Integer id) {
return userFeign.getUserById(id); // 像本地调用一样丝滑!
}
🎭 原理:动态代理的"障眼法"
@EnableFeignClients启动后,扫描@FeignClient接口,生成动态代理类交给Spring管。调用接口方法时,代理类偷偷创建请求模板,背后用Ribbon选服务实例。
技术内幕:Feign通过JDK动态代理生成实现类,再通过Contract解析注解,最终使用Ribbon进行负载均衡。
📬 传参秘籍:三种姿势任你挑!
a. 问号传参 :@RequestParam("sb") → URL?sb=250,适合简单参数
b. Restful传参 :@PathVariable("sb") → URL/sb/250,优雅如诗
c. POJO传参:@RequestBody → 对象自动变JSON,适合复杂数据
使用技巧:
- 简单参数用@RequestParam
- 路径参数用@PathVariable
- 复杂对象用@RequestBody
- 头部信息用@RequestHeader
三、Feign请求超时?试试"耐心特训" ⏳
⏱️ 模拟超时场景:在服务提供方故意"拖延"
@Service
public class UserServiceImpl {
@Override
public User getUser() {
try {
Thread.sleep(2000); // 假装处理很慢...
} catch (InterruptedException e) {}
return new User(1, "王粪堆", 18);
}
}
⚙️ 设置超时时间(别让Feign等成"望妻石")
application.yml加配置:
ribbon:
ConnectTimeout: 5000 # 连接超时5秒(别急,慢慢连)
ReadTimeout: 5000 # 处理超时5秒(别催,慢慢处理)
超时配置小贴士:"服务慢了别干等,调大超时时间,给它点'缓冲空间'~"
四、Ribbon vs Feign:谁更胜一筹? 🏆
📊 功能对比
| 特性 | Ribbon | Feign |
|---|---|---|
| 负载均衡 | ✓ | ✓(基于Ribbon) |
| 声明式调用 | ✗ | ✓ |
| 注解支持 | 简单 | 丰富 |
| 使用复杂度 | 中等 | 简单 |
| 性能 | 较高 | 稍低 |
🎯 适用场景
- Ribbon:需要精细控制负载均衡策略
- Feign:追求开发效率,喜欢声明式编程
五、最佳实践与避坑指南 🧭
✅ 成功要素
- 确保模块间依赖正确,别让Feign找不到"桥"(feign_interface)
- 超时配置要结合实际业务场景,避免因等待过久影响系统响应
- 给服务留足"喘息空间",合理设置超时时间
- 监控服务调用情况,及时发现异常
⚠️ 常见坑点
- 忘记@EnableFeignClients:Feign无法扫描到接口
- 依赖缺失:feign_interface模块没引入
- 超时设置不合理:太短导致频繁失败,太长影响响应
- 服务名写错:@FeignClient("服务名")要和注册中心一致
六、扩展知识:Feign的高级玩法 🎓
🌈 日志配置
logging:
level:
com.example.feign: DEBUG
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // NONE, BASIC, HEADERS, FULL
}
🔒 请求拦截器
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
requestTemplate.header("Authorization", "Bearer token");
};
}
七、总结:微服务调用的艺术 🎨
🌟 核心收获
- Ribbon是负载均衡的基石,提供了丰富的策略选择
- Feign是开发效率的利器,让远程调用像本地方法一样简单
- 合理配置超时,平衡用户体验和系统稳定性
- 选择合适的工具,根据业务需求决定使用Ribbon还是Feign