04 微服务组件 - Feign服务调用

166 阅读5分钟

1. Java项目中如何实现接口调用?

  1. HttpClient:相较于传统JDK自带的URLConnection,提升了易用性和灵活性,使客户端发送Http请求变得更容易;
  2. Okhttp:一个处理网络请求的开源项目,是安卓端最火的轻量级框架;
  3. HttpURLConnection:Java的标准类,继承自URLConnection,可用于向指定网站发送GET、POST请求,使用复杂;
  4. RestTemplate:Spring提供的用于访问Rest服务的客户端,提供了多种访问Http服务的方法,大大提高开发效率。

2. 什么是Feign?

Feign是Netflix开发的声明式、模板化的 **Http客户端** ,可以帮助我们更加便捷、优雅的调用Http Api

SpringCloud OpenFeign对Feign进行了增强,使其支持SpringMVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便

优势: Feign可以做到使用Http请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个Http请求。它像Dubbo一样consumer直接调用接口方法调用provider而不需要通过常规的HttpClient构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。

3. SpringCloud Alibaba快速整合OpenFeign

快速整合步骤:order服务调用stock服务

  1. 引入依赖:
<!--openfeign远程调用-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 编写调用接口:
@FeignClient(value = "stock-service", path = "/stock")
public interface StockFeignClient {

    @PostMapping("/query")
    String query(@RequestBody Object obj);
}
  1. 启动类上添加@EnableFeignClients注解:
@SpringBootApplication
@EnableFeignClients
public class OrderApp {

    public static void main(String[] args) {
        SpringApplication.run(OrderApp.class, args);
    }
}
  1. 发起调用:
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private StockFeignClient stockFeignClient;

    @PostMapping("/query2")
    public String query2(@RequestBody Object obj) {
        log.debug("订单请求req2:{}", JSON.toJSON(obj));
        return  stockFeignClient.query(obj);
    }
}

4. SpringCloud Feign的自定义配置及使用

Feign提供了很多的拓展机制,让用户可以更加灵活的使用。

4.1 日志配置

有时候我们遇到Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置Feign的日志了,以此让Feign把请求信息输出来。

全局配置方式:

@Configuration
public class FeignConfig {

    // 此种配置将对所有调用的服务生效
    @Bean
    public Logger.Level logLevel() {
        return Logger.Level.FULL;
    }
}

Feign日志有4种级别,分别是:

  • NONE【性能最佳,适用于生产】:不记录任何日志(默认值);
  • BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间;
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header;
  • FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

局部配置方式:

# 日志级别
logging.level.com.balloon=debug
#feign日志级别-指定服务
feign.client.config.stock-service.logger-level=FULL

对应的配置类:org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration

4.2 超时时间配置

通过Options可以配置连接超时时间和读取超时时间,Options的第一个参数是连接的超时时间(ms),默认值是10*1000ms,第二个是请求处理的超时时间(ms),默认值是60*1000ms。

全局配置方式:

@Bean
public Request.Options options() {
    return new Request.Options(5000, 1000);
}

局部配置方式:

#feign超时配置-指定服务
feign.client.config.stock-service.connect-timeout=5000
feign.client.config.stock-service.read-timeout=1000

补充说明:Feign的底层用的是Ribbon,但超时时间以Feign配置为准!

4.3 客户端组件配置

Feign中默认使用JDK原生的URLConnection发送HTTP请求,我们可以集成别的组件来替换掉URLConnection,比如Apache HttpClient、OkHttp。 Feign发起调用真正执行逻辑:feign.Client#execute

image.png

配置Apache HttpClient:

  1. 引入依赖:
<!--Apache HttpClient-->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.7</version>
</dependency>
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
    <version>10.1.0</version>
</dependency>
  1. 修改配置,启用Feign的Apache HttpClient:
#feign使用Apache HttpClient(可以忽略,默认开启)
feign.httpclient.enabled=true

关于配置可参考源码:org.springframework.cloud.openfeign.FeignAutoConfiguration image.png

测试:调用会进入feign.httpclient.ApacheHttpClient#execute


拓展学习

  • openFeign夺命连环9问,这谁受得了?(Feign也是一个狠角色,Feign旨在使得Java Http客户端变得更容易Feign集成了Ribbon、RestTemplate实现了负载均衡的执行Http调用;Feign = Ribbon(客户端负载均衡)+ RestTemplate(http调用)
  • hystrix ,feign,ribbon的超时时间配置,以及原理分析(openFeign默认连接时间/超时时间为20s/60s,ribbon为1s/1s;取值逻辑:都不配取ribbon默认的1s/1s,配了优先取openFeignimage.png
  • 强强联合:OpenFeign 整合 SentinelopenFeign+sentinel实现服务降级
  • Spring Cloud OpenFeign远程调用性能优化优化:超时时间+线程池管理http连接对象+传输数据压缩+负责均衡策略+日志级别
    1. 修改openFeign的超时时间,让openFeign能够正确的处理业务;
    2. 通过配置专用的通信组件Apache HttpClient 或 OKHttp ,让 OpenFeign 可以通过线程池更好地对 HTTP 连接对象进行重用和管理,以提高其性能;
    3. 开启数据压缩功能,可以提高宽带利用率和加速数据传输速度;
    4. 使用合适的负载均衡策略来替换默认的轮询负载均衡策略,已获得更好的执行效率;
    5. 检查生产环境中 openFeign 的日志级别,选择合适的日志输出级别,防止无效的日志输出。
  • 微服务中远程调用Dubbo与Feign对比 (dubbo与feign都依赖注册中心、负载均衡;dubbo性能高、支持多协议、默认的Dubbo协议:利用Netty,TCP传输,单一、异步、长连接,适合数据量小、高并发 和服务提供者远远少于消费者的场景
  • Dubbo 、 OpenFegin 远程服务调用的使用区别
    • 个人观点:dubbo使用体验更好:1)超时、重试配置一目了然 2)可直接引用服务提供方接口定义
  • 今天就先到这里吧??? 生命不息 学习不止!!!
  • 重学springboot系列番外篇之RestTemplateRestTemplate是一个用于发送HTTP请求的工具类,使用JDK自带的httpURLConnection作为底层http客户端实现image.png

迷之操作

在实际生产中,发现openFeign的使用和上面学的demo有很大出入??? image.png

解答:openFeigin有两种使用方式:1.指定访问URL 2.不指定访问URL(配置的name值用于服务发现) 参见:# 那天晚上和@FeignClient注解的深度交流

image.png