OpenFeign和Feign

一:前言

        之前微服务之间调用使用的RestTemplate,调用比较复杂,URL需要拼接,使用不太方便Feign是SpringCloud提供的声明式的HTTP客户端,只用编写接口,就能够通过http请求实现服务的调用OpenFeign是Feign的扩展,能够支持SpringMVC的注解OpenFeign = RestTemplate + Ribbon + Hystrix

二:OpenFeign是什么

        Feign是一个声明式的Web服务客户端(Web服务客户端就是Http客户端),让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。

cloud官网介绍Feign:Spring Cloud OpenFeign 

 三:OpenFeign能干什么

        Java当中常见的Http客户端有很多,除了Feign,类似的还有Apache 的 HttpClient 以及OKHttp3,还有SpringBoot自带的RestTemplate这些都是Java当中常用的HTTP 请求工具。 

什么是Http客户端?

当我们自己的后端项目中 需要 调用别的项目的接口的时候,就需要通过Http客户端来调用。在实际开发当中经常会遇到这种场景,比如微服务之间调用,除了微服务之外,可能有时候会涉及到对接一些第三方接口也需要使用到 Http客户端 来调用 第三方接口。 

所有的客户端相比较,Feign更加简单一点,在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定。 

四: OpenFeign的特点和优势

  • 声明式的调用:使用OpenFeign,开发人员只需要定义接口并添加注解,就可以轻松地调用HTTP API,而无需手动编写HTTP请求和处理响应的代码。
  • 自动序列化和反序列化:OpenFeign可以自动处理请求和响应的序列化和反序列化,无需手动转换JSON数据。
  • 请求和响应拦截器:OpenFeign提供了拦截器的支持,开发人员可以在请求和响应的过程中添加自定义的逻辑。
  • 整合Netflix生态系统:OpenFeign可以与Netflix的其他库(如Hystrix和Ribbon)无缝集成,提供容错和负载均衡的功能。

五:Feign和OpenFeign的区别

Feign:

        Feign是SpringCloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务

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

 OpenFeign

OpenFeign 是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign 的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

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

六:OpenFeign的使用

 ① openFeign的依赖

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

② 编写Feign客户端接口

/**
 * 调用商品服务的Feign客户端
 * @FeignClient需要设置调用的服务名
 */
@FeignClient("product-service")
public interface ProductServiceFeignClient{

    /**
     * 调用商品id查询
     * @param id
     * @return
     */
    @GetMapping("/product/{id}")
    ResponseEntity<Product> getProductById(@PathVariable Long id);
}

③ 启动类加注解扫描feign接口@EnableFeignClients(basePackages = "com.blb.orderservice.feign")

④ 调用服务时

@Autowired
private ProductServiceFeignClient productServiceFeignClient;


//使用feign客户端调用服务
ResponseEntity<Product> entity = productServiceFeignClient.getProductById(order.getProductId());

 七:Feign简介

        Feign是一个声明式的Web服务客户端,它可以轻松地调用其他微服务的API。它基于注解和反射机制,可以自动生成HTTP请求和响应的代码,从而减少了手动编写HTTP客户端的工作量。

八:Feign的特点和优势

  • 声明式的调用:使用Feign,开发人员只需要定义接口并添加注解,就可以轻松地调用其他微服务的API,而无需手动编写HTTP请求和处理响应的代码。
  • 自动负载均衡:Feign集成了Ribbon负载均衡器,可以自动分发请求到多个实例上,提高了系统的可用性和性能。
  • 整合Netflix生态系统:Feign可以与Netflix的其他库(如Hystrix和Eureka)无缝集成,提供容错和服务发现的功能。
  • 支持多种协议:除了HTTP,Feign还支持使用其他协议(如HTTP2和WebSocket)进行通信。

 九:Feign整合Ribbon

Feign默认整合了Ribbon实现负载均衡

  • 全局配置

    ribbon.属性 = 值

  • 指定服务配置

    服务名称.ribbon.属性 = 值

Ribbon常用配置:

  • ConnectionTimeout 连接超时

  • ReadTimeout 读取超时

  • OkToRetryOnAllOperations 对所有操作启动重试机制 true/false

  • MaxAutoRetries 最大重试次数

  • MaxAutoRetriesNextServer 最大重试下个服务器次数

① 引入相关依赖

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

<!-- Ribbon -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

② 在启动类上添加@EnableFeignClients注解,启用Feign客户端功能

@SpringBootApplication
@EnableFeignClients
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

③ 在Feign客户端接口的@FeignClient注解中使用configuration属性指定Ribbon的配置类。

@FeignClient(name = "user-service", configuration = RibbonConfig.class)
public interface UserServiceClient {
    // 定义远程服务的接口方法...
}

④ 创建Ribbon的配置类RibbonConfig,并使用@Configuration注解进行标记。在配置类中可以定制Ribbon的负载均衡策略等相关配置。

java
@Configuration
public class RibbonConfig {

    @Bean
    public IRule ribbonRule() {
        return new RandomRule(); // 使用随机负载均衡策略
    }

    // 其他配置...
}

⑤ 最后,在需要使用Feign的地方注入Feign客户端接口,并直接调用方法即可。

@RestController
public class UserController {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        return userServiceClient.getUserById(id);
    }
    
    // 其他业务代码...
}

通过以上步骤,就可以在Feign中成功整合Ribbon来实现服务调用的负载均衡功能了。 

十: Feign整合Hystrix

Feign默认整合了Hystrix的熔断机制

Feign可以单独定义类,编写降级方法

实现:

1)定义降级处理类,实现对应的FeignClient接口

2)实现接口中的方法,所有方法均为降级方法

/**
 * 降级处理类
 */
@Component
public class ProductServiceFallback implements ProductServiceFeignClient {

    /**
     * 降级方法返回兜底数据
     */
    @Override
    public ResponseEntity<Product> getProductById(Long id) {
        Product product = new Product(id,"降级数据", BigDecimal.valueOf(0),"测试");
        return ResponseEntity.ok(product);
    }

}

3)在FeignClient注解中配置降级方法处理类

@FeignClient(value = "product-service",fallback = ProductServiceFallback.class)

4)启动Feign的Hystrix特性

feign.hystrix.enabled=true

 PS: 如果feign接口和降级类和服务提供者项目不是同一个项目,需要加包的扫描

@SpringBootApplication(scanBasePackages = {"com.blb.orderservice","com.blb.common"})

十一: Feign的优化配置

1. 优化连接池

        Feign是基于HTTP协议,HTTP协议基于TCP协议,TCP具有三次握手四次挥手机制,频繁的创建连接比较消耗系统的资源和时间,降低系统的吞吐量。      

        使用连接池可以减少网络连接的创建,提高连接的使用效率,提高系统吞吐量。    

        Feign默认使用JDK自带的HttpURLConnection,没有连接池。可以使用HttpClient或OkHttp

 使用步骤:

1)导入feign-httpclient依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

2)feign.httpclient.enable=true

2. 请求压缩优化

Feign可以对网络数据进行GZIP压缩,减少网络流量,提高速度

GZIP是什么

        gzip是一种数据格式,采用deflate算法为进行数据压缩;gzip是一种非常流行的文件压缩算法,在Linux平台再是平常不过了

GZIP有什么用

        当gzip压缩一个纯文本文件时,大约可以减少7成以上的文件大小;从这你就可以看出压缩能力多强悍,这样一来加快了网页加载的速度,提高了用户体验。 

启动压缩:  

#启动请求压缩 
feign.compression.request.enabled=true 
#启动响应压缩 
feign.compression.response.enabled=true 
#设置请求压缩的多媒体类型 
feign.compression.request.mime-types=text/html,application/xml,application/json 
#设置请求压缩的下限 (默认2048)
feign.compression.request.min-request-size=1024 

3.使用日志对连接过程进行监控

1)开启debug日志

logging.level.包名.FeignClient接口名=DEBUG

2)定义配置类,配置日志

/** Feign日志配置  */ 
@Configuration 
public class FeignLoggerConfig {      
    /**  返回日志类型,NONE没有日志,BASIC基本信息(请求方法,URL,响应代码等),HEADERS(头部信息),FULL(基本+头部)*/     
    @Bean     
    public Logger.Level level(){         
    	return Logger.Level.BASIC;     
    } 
} 

4. 超时优化

        Ribbon是具有重试机制的,就是连接失败后进行重连,问题是:Hystrix的超时时间默认是小于Ribbon的超时,Hystrix会提前熔断,Ribbon无法进行重试

        Feign底层设置的超时时间为一秒,时间太短了如果超时就会异常,可以添加一个线程睡眠测试一下,线程睡眠1.5秒

 @Override
    public User getUserById(Integer id) {
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id, "小明1", 22);
    }

浏览器报错页面

 后端抛出异常

 把超时时间延长配置上后重新测试,并且这次睡眠时间设置为4秒

server:
  port: 9006
  compression:
    enabled: true #开启浏览器<----->consumer的gzip压缩
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.65.132:8848 #注册中心的地址
  application:
    name: feign-consumer #注册的名字
feign:
  compression:
    request:
      enabled: true #开启feign<---->provider的gzip压缩
    response:
      enabled: true
  client:
    config:
      feign-provider:
          ConnectionTimeout: 5000 #请求连接的超时时间
          ReadTimeout: 5000 #请求处理的超时时间

Hystrix的超时要大于Ribbon的超时

# hystrix的超时 
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000 
# ribbon的超时 
ribbon.ConnectionTimeout=1000 
ribbon.ReadTimeout=3000

 十二:Feign工作原理

为什么Feign只需要编写接口就能完成远程服务的调用

关键技术:

  • IOC

  • 动态代理

  • HTTP网络连接

 实现步骤:

1) 添加@EnableFeignClients后,对Feign接口进行扫描,加载FeignClient接口信息到IOC容器中

2) 使用JDK动态代理创建FeignClient接口的实现类

3) 在JDK动态代理的InvocationHandler中的invoke方法实现方法的调用,创建RequestTemplate对象

4) 将RequestTemplate对象交给负载均衡器处理,对请求进行编码,发送HTTP请求

5) 获得响应,对响应进行解码,返回数据

 十三:总结

         OpenFeign是一个强大而简单的工具,可以极大地简化HTTP API调用的过程。它的声明式调用方式、自动序列化和反序列化功能以及与Netflix生态系统的整合,使开发人员能够更专注于业务逻辑的实现,而无需过多关注底层的HTTP请求和响应处理。

        Feign是一个强大而简单的工具,可以极大地简化微服务间的通信。它的声明式调用方式、自动负载均衡功能以及与Netflix生态系统的整合,使开发人员能够更专注于业务逻辑的实现,而无需过多关注底层的HTTP请求和响应处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值