OpenFeign教程

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 由浅入深拿下OpenFeign

1、OpenFeign是什么?

OpenFeign是一个Web声明式的Http客户端调用工具。是Spring Cloud官方对Feign的增强,它支持spring mvc的注解。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样。

2、环境准备

本文基于Springboot 2.6.8,服务注册中心使用的Nacos 版本用的最新的2021.0.1.0。看一下相关的Pom依赖

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--spring-cloud-starter-alibaba-nacos-config--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2021.0.1.0</version></dependency><!--spring-cloud-starter-alibaba-nacos-discovery--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2021.0.1.0</version><!--不使用Ribbon进行客户端负载均衡--><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.0.4</version></dependency>

这里简单讲解一下,不是本文重点:  

  1. 由于Ribbon停止维护,所以新版的SpringCloud已经不用它了,所以需要引入spring-cloud-starter-loadbalancer,并且在nacos依赖中排除掉ribbon。
  2. Springboot2.4+需要引入spring-cloud-starter-bootstrap

3、服务提供者

bootstrap.yml

server:
port: 8081spring:
cloud:
nacos:
discovery:
server-addr: ipservice: provider

新建接口

@RestController@RequestMapping("/provider")
publicclassProviderController {
@PostMapping("/getOrder")
OrdergetOrder(@RequestBodyOrderRequestrequest){
System.out.println(request.getId());
System.out.println(request.getClassify());
returnOrder.builder().code("JSON数据").build();
    }
@GetMapping("/findOrder/{id}")
OrderfindOrder(@PathVariable("id") Integerid){
returnOrder.builder().id(id).count(50).code("URL携带参数").build();
    }
@GetMapping("/findOrder")
OrderfindOrder(@SpringQueryMapOrderRequestrequest){
returnOrder.builder().code("POJO表单参数").build();
    }
@GetMapping("/findOrder2")
OrderqueryOrder(@RequestParam("id") Integerid,
@RequestParam("code") Stringcode){
System.out.println(id);
System.out.println(code);
returnOrder.builder().code("普通表单参数").build();
    }

订单实体类

@Data@BuilderpublicclassOrder {
privateIntegerid;
privateStringcode;
privateIntegeruserId;
privateIntegercount;
privateBigDecimalmoney;
}

查询参数类

@DatapublicclassOrderRequest {
privateIntegerid;
privateStringname;
privateStringclassify;
privateIntegernumber;
}

4、服务消费者

bootstrap.yml

server:
port: 8082spring:
cloud:
nacos:
discovery:
server-addr: ipservice: consumer
  • @EnableFeignClients  启用Feign客户端
  • @FeignClient 标记Feign客户端  

在主程序的上加上注解@EnableFeignClients

新建一个接口 name填服务提供者注册到nacos的服务名

@FeignClient(name="provider",path="provider")
publicinterfaceFeignProviderService {
@PostMapping("/getOrder")
OrdergetOrder(@RequestBodyOrderRequestrequest);
@GetMapping("/findOrder/{id}")
OrderfindOrder(@PathVariable("id") Integerid);
@GetMapping("/findOrder")
OrderfindOrder(@SpringQueryMapOrderRequestrequest);
@GetMapping("/findOrder2")
OrderqueryOrder(@RequestParam("id") Integerid,
@RequestParam("code") Stringcode);
}

这样就可以在消费者的Service中直接注入使用

@Service("consumerService")
publicclassConsumerServiceImplimplementsConsumerService {
@AutowiredFeignProviderServicefeignProviderService;
@OverridepublicOrderdealOne() {
OrderRequestorderRequest=newOrderRequest();
orderRequest.setId(1);
orderRequest.setClassify("777");
returnfeignProviderService.getOrder(orderRequest);
    }
@OverridepublicOrderdealTwo() {
returnfeignProviderService.findOrder(2);
    }
@OverridepublicOrderdealThree() {
OrderRequestorderRequest=newOrderRequest();
orderRequest.setId(3);
orderRequest.setNumber(555);
returnfeignProviderService.findOrder(orderRequest);
    }
@OverridepublicOrderdealFour() {
returnfeignProviderService.queryOrder(4,"ORDER-FOUR");
    }
}

5、传参问题

上文也看到我们在接口类中定义了不同传参方式的API

5.1 传递JSON数据

这个也是接口开发中常用的传参规则,在Spring Boot 中通过@RequestBody标识入参。openFeign默认的传参方式就是JSON传参(@RequestBody),因此定义接口的时候可以不用@RequestBody注解标注,不过为了规范,一般都填上。

5.2 POJO表单传参

openFeign提供了一个注解@SpringQueryMap完美解决POJO表单传参。

5.3 URL携带参数

此种方式针对restful方式中的GET请求,也是比较常用请求方式。

5.4 普通传参

这种不管调用方还是被调用方都加上@RequestParam注解

6、超时处理

如果连接或者读取时间超过了默认超时时间,消费者端就会报超时。

旧版本集成Ribbon如果不设置超时时间,默认超时时间为1s,新版不用Ribbon了。

在消费端的配置文件中配置超时时间

feign:
client:
config:
##default设置的全局超时时间,指定服务名称可以设置单个服务的超时时间default:
connectTimeout: 5000readTimeout: 5000

还可以给单个服务配置超时时间,单个配置的超时时间将会覆盖全局配置。

feign:
client:
config:
##default设置的全局超时时间,指定服务名称可以设置单个服务的超时时间default:
connectTimeout: 5000readTimeout: 5000##为serviceC这个服务单独配置超时时间serviceC:
connectTimeout: 30000readTimeout: 30000

7、开启日志增强

feign的日志级别

  • NONE: 默认的,不显示任何日志
  • BASIC: 仅记录请求方法、URL、响应状态码以及执行时间
  • HEADERS:除了BASIC 中自定义的信息外,还有请求和响应的信息头
  • FULL: 除了HEADERS中定义的信息外, 还有请求和响应的正文以及元数据。

前提条件需要在配置文件中,将日志级别设置为DEBUG。我们修改一下消费者的配置文件

feign:
client:
config:
##default设置的全局超时时间,指定服务名称可以设置单个服务的超时时间default:
connectTimeout: 5000readTimeout: 5000loggerLevel: basiclogging:
level:
#feign接口pathcom.example.consumer.client.FeignProviderService: debug

再次调用服务可以看到控制台有相关日志了

8、替换默认HttpClient

ApacheHttpClient和默认实现的比较

  • Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection。
  • ApacheHttpClient实现了连接池,同时它封装了访问http的请求头,参数,内容体,响应等等,使客户端发送 HTTP 请求变得容易

添加依赖

<!--httpclient--><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency><!--feign-httpclient--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>10.10.1</version></dependency>

可以看到,默认就是开启的

9、工作原理

远程调用基本流程

其中 MethodHandler 的invoke(…)方法,主要职责是完成实际远程URL请求,然后返回解码后的远程URL的响应结果

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
负载均衡 架构师 Java
详细讲解OpenFeign的使用姿势!
学会使用Feign最贱优雅地调用服务
23191 9
详细讲解OpenFeign的使用姿势!
|
SpringCloudAlibaba 网络协议 Cloud Native
Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。
14846 2
Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)
|
前端开发 网络协议 Dubbo
超详细Netty入门,看这篇就够了!
本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。
91418 32
超详细Netty入门,看这篇就够了!
|
6月前
|
SpringCloudAlibaba Java Nacos
尚硅谷SpringCloud教程 笔记
本文介绍了基于Spring Cloud Alibaba构建的cloud-demo工程创建步骤,包括父模块及子模块的配置。父模块采用pom打包方式,定义了Java 8、Spring Boot 2.4.2、Spring Cloud 2020.0.1及Spring Cloud Alibaba 2021.1版本。包含三个主要模块:services(依赖Nacos)、service-order和service-product(均依赖spring-boot-starter-web)。同时提供了discoveryClient的测试代码,展示服务发现功能的实现与验证过程。
354 12
尚硅谷SpringCloud教程 笔记
|
存储 JSON NoSQL
JSON 存入 Redis
【7月更文挑战第8天】
350 12
|
负载均衡 Java API
Java一分钟之-Spring Cloud OpenFeign:声明式服务调用
【6月更文挑战第9天】Spring Cloud OpenFeign是声明式服务调用库,简化了微服务间调用。通过动态代理,它允许开发者用Java接口调用HTTP服务,支持服务发现、负载均衡。本文介绍了OpenFeign的基本概念,展示了如何添加依赖、开启客户端和定义服务接口。还讨论了接口调用失败、超时重试和日志配置等问题及其解决方案,并提供了自定义Feign配置的代码示例。通过学习,读者可以更好地在微服务架构中使用OpenFeign进行服务通信。
576 4
|
10月前
|
机器学习/深度学习 自然语言处理 监控
智能客服系统集成技术解析和价值点梳理
在 2024 年的智能客服系统领域,合力亿捷等服务商凭借其卓越的技术实力引领潮流,它们均积极应用最新的大模型技术,推动智能客服的进步。
430 7
|
12月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
XML JSON Java
OpenFeign深入学习笔记
OpenFeign 是 Spring Cloud 生态系统中的一个强大工具,它使得微服务之间的通信变得更加简单和高效。通过使用 OpenFeign,开发者可以专注于业务逻辑的实现,而不需要关心底层的 HTTP 通信细节。
219 0
|
前端开发 架构师 Java
领域驱动设计DDD从入门到代码实践
在本文中,作者将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。
14864 11
领域驱动设计DDD从入门到代码实践