OpenFeign
OpenFeign客户端是一个web声明式http远程调用工具,直接可以根据服务名称去注册中心拿到指定的服务IP集合,提供了接口和注解方式进行调用,内嵌集成了Ribbon本地负载均衡器。
feign和OpenFeign的区别
1、底层都是内置了Ribbon,去调用注册中心的服务。
2、Feign是Netflix公司写的,是SpringCloud组件中的一个轻量级RESTful的HTTP服务客户端,是SpringCloud中的第一代负载均衡客户端。
3、OpenFeign是SpringCloud自己研发的,在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。是SpringCloud中的第二代负载均衡客户端。
4、Feign本身不支持Spring MVC的注解,使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
5、OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
Springcloud alibaba集成OpenFeign
业务API
在
service下引入依赖<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>在
service-order下类package com.lazy.cloud.feign;
public interface OrderOpenFeignClient {
public Product getProduct( Integer productId);
}serviceImpl层,其他的不变package com.lazy.cloud.service.impl;
public class OrderServiceImpl implements OrderService {
private OrderOpenFeignClient orderOpenFeignClient;
public Order addOrder(Long userId, Long productId) {
Product product = orderOpenFeignClient.getProduct(productId);
BigDecimal price = product.getPrice().multiply(new BigDecimal(product.getNum()));
return new Order(userId, price, productId, "河北", List.of(product));
}
}主启动类上添加
@EnableFeignClients启动
service-order服务和service-product,测试一下
远程调用-业务API(第三方API)
引入
OpenFeign依赖<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>编写
feignClient接口package com.lazy.cloud.feign;
/**
* url 为请求的网址
* value 因为不是本底的,随便起的名
*/
public interface HotOpenFeignClient {
/**
*
* @param key 网址需要请求的参数
* @return 返回今日头条热搜榜
*/
public String getTou( String key);
}在主启动类上添加
@EnableFeignClients注解在测试类上测试
package com.lazy.cloud;
public class HotOpenFeignClientTest {
private HotOpenFeignClient hotOpenFeignClient;
public void test() {
System.out.println(hotOpenFeignClient.getTou("36de5db81215"));
}
}结果

客户端负载均衡和服务端负载均衡的区别

服务端的负载均衡是一个url先经过一个代理服务器(这里是nginx),然后通过这个代理服务器通过算法(轮询,随机,权重等等)反向代理你的服务,来完成负载均衡。
而客户端的负载均衡则是一个请求在客户端的时候已经通过eureka获取了要调用服务的集群信息,然后通过具体的负载均衡算法来完成调用具体某个服务。
简而言之,服务端负载均衡需要先经过nginx代理服务器才能知道调用服务的集群信息。而客户端负载均衡请求在客户端的时候就已经知道了调用服务的集群信息。
关键对比总结
| 维度 | 客户端负载均衡 | 服务端负载均衡 |
|---|---|---|
| 决策位置 | 客户端 | 独立的负载均衡器(代理层) |
| 性能 | 更优(无中间跳转) | 略低(需经过代理) |
| 复杂度 | 客户端逻辑复杂 | 客户端无需感知负载逻辑 |
| 服务发现 | 强依赖(如Eureka) | 可选(如Nginx手动配置或结合DNS) |
| 多语言支持 | 差(需各语言实现) | 好(客户端透明) |
| 典型工具 | Ribbon、Spring Cloud LoadBalancer | Nginx、HAProxy、AWS ELB |
OpenFeign日志

如何开启日志
添加配置文件,配置日志
logging:
level:
com.lazy.cloud.feign: debug # com.lazy.cloud.feign包名,可以精确到类名,debug级别添加
@Bean
public class FooConfiguration {
Logger.Level feignLoggerLevel() { //Logger一定要导入 feign包下的
return Logger.Level.FULL;
}
}
测试

超时控制
如果商品服务一直连接不上,或API读取慢,或读不到,有可能会造成服务雪崩的问题,针对这个问题我们要使用超时控制来解决!
我们引入超时控制,来解决这个问题,我们设置上请求多少秒,为超时,如果超时,会返回“网络繁忙”,或者“兜底数据”,兜底数据,需要结合Sentinel 来实现,以我们现在的技术只能返回”网络繁忙”
超时分两种connectTimeout(超时控制,默认为10秒)和readTimeout(读取超时,默认为60秒)我们可以通过配置修改它的超时时间

application.yml
server: |
application-feign.yaml
spring: |
修改service-product项目的controller类,让他睡上20秒
package com.lazy.cloud.controller; |
启动测试一下

使用默认配置再试试

重试机制
远程调用超时失败后,还可以进行多次尝试,如果某次返回ok,如果多次依然失败则结束调用,返回错误
但是OpenFeign,默认没有使用重试机制

默认重试器,间隔100毫秒,最大间隔1秒,默认重试5次
因为第一次重试是100毫秒,第二次间隔100*1.5毫秒,第三次间隔100*1.5*1.5毫秒,依次类推,最大间隔1秒

添加重试
package com.lazy.cloud.config; |
运行测试,发现打印了五次productController,重试了五次

这个重试机制,是加上设置的超时时间,再加上延迟等待时间
OpenFeign拦截器
请求拦截器RequestInterceptor
发送请求时,由请求拦截器进行最后拦截,可以对请求进行定制修改
响应拦截器ResponseInterceptor
可以对响应的数据进行预处理
需求,service-order定义XTokenInterceptor拦截器,向service-product发送请求的时候带上x-token:
第一种方式
package com.lazy.cloud.interceptor; |
service-product
package com.lazy.cloud.controller; |
发起http://localhost:8000/addOrder?userId=1&productId=100

第二种方式
package com.lazy.cloud.interceptor; |
yaml
spring: |
service-product不变

FallBack
FallBack:兜底返回
注意:
此功能需要整合
sentienl才能实现
整合FallBack
添加
sentienl依赖<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>编写
OrderOpenFeignFallBack实现OrderOpenFeign接口package com.lazy.cloud.feign.fallback;
public class OrderOpenFeignClientFallBack implements OrderOpenFeignClient {
public Product getProduct(Long productId) {
Product product = new Product(productId,new BigDecimal("0"),"未知商品",0);
return product;
}
}在
OrderOpenFeignClient类配置,兜底返回package com.lazy.cloud.feign;
//fallback 配置兜底返回
public interface OrderOpenFeignClient {
public Product getProduct( Long productId);
}开启熔断功能
feign:
sentinel:
enabled: true先启动
service-order,不启动service-product,看看能不能实现兜底返回
在启动
service-product


