Spring Cloud OpenFeign是Spring Cloud生态系统中的一部分,它提供了一种声明式的、简化的方式来调用RESTful服务。它使得开发人员可以使用注释和接口定义来描述对服务的请求,并且它可以自动地生成客户端代码来处理这些请求。
使用Spring Cloud OpenFeign,开发人员可以通过简单地定义接口来调用远程服务。开发人员只需要使用Spring MVC的注释,例如@GetMapping和@PostMapping,定义接口,OpenFeign就可以自动地将这些接口映射到RESTful服务。开发人员还可以使用Fallback功能来处理远程服务的失败。
Spring Cloud OpenFeign还提供了一些其他功能,例如服务发现和负载均衡。这些功能可以与Eureka、Consul、Zookeeper等服务注册中心集成,以便在分布式系统中使用。
前几章我们通过了Ribbon+RestTemplate实现了服务的远程调用,但是有很多缺陷,OpenFeign在此基础上做了一些封装,使其有了更好的优势
底层实现:OpenFeign底层依赖于Spring Cloud和Spring MVC,而Feign底层依赖于Netflix的开源项目。
注解支持:OpenFeign支持Spring MVC注解,例如@RequestParam、@RequestBody等,而Feign则需要使用自己的注解。
自定义契约:OpenFeign可以通过实现自定义契约来扩展和定制化,而Feign则没有这样的扩展方式。
断路器支持:OpenFeign集成了Hystrix,而Feign需要单独引入Hystrix来实现断路器支持。
拦截器支持:OpenFeign提供了更加灵活和全面的HTTP请求和响应拦截器支持,可以对请求和响应进行更加细粒度的处理,而Feign的拦截器支持相对较少。
OpenFeign在底层实现、注解支持、自定义契约、断路器支持和拦截器支持等方面与Feign有所不同。根据具体的业务需求和开发背景,选择合适的框架来进行开发和调用RESTful服务。
新建一个调用服务module,还是参照auth服务,具体的服务调用我们从RestTemplate换成OpenFeign
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
server:
port: 9002
spring:
application:
name: lf-auth
eureka:
instance:
# 配置eureka的状态显示
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
启动类
主要是添加@EnableFeignClients注解
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignAuthApplication {
public static void main(String[] args) {
SpringApplication.run(FeignAuthApplication.class,args);
}
}
service接口
新增注解@FeignClient通过业务逻辑接口+@FeignClient配置调用LF-USER服务
@FeignClient(value = "LF-USER")
public interface AuthService {
@GetMapping("/user/info/{username}")
String getUserInfo(@PathVariable("username") String username);
}
controller
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
AuthService authService;
@PostMapping("login")
public String login(@RequestBody String name)
{
return authService.getUserInfo(name);
}
}
如下图,官网说明,OpenFeign是有默认的超时时间的,分别是连接超时时间和读超时时间
查看源码默认连接超时时间10s和读超时时间 60s;
我们测试下,在9001端口的user服务端加一个3s延时。 并且只启动这个服务端。
结果会发现报错超时了。
为什么我们只设置了睡眠3秒就报超时呢?远没有达到上面的连接超时和读超时时间。其实 openFeign 集成了 Ribbon,Ribbon 的默认超时连接时间、读超时时间都是是1秒,源码如下图:
如果没有设置openFeign 的默认超时时间就会取Ribbon的超时时间
修改lf-feign-auth服务的yml文件
ribbon:
# 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间
ReadTimeout: 5000
# 指的是建立链接后从服务器读取可用资源所用的时间
ConectTimeout: 5000
feign:
client:
config:
## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
default:
connectTimeout: 5000
readTimeout: 5000
在 OpenFeign 中,超时时间是由客户端的配置文件指定的。在这个配置文件中,可以为每个服务实例设置单独的超时时间。这样可以更加精确地控制超时时间,因为不同的服务实例可能具有不同的响应时间。如果在 Ribbon 中设置超时时间,则可能会将请求分配到响应时间较长的服务实例上,从而导致请求超时,而无法得到及时的响应。
此外,如果使用 Ribbon 进行负载均衡时,超时时间还会受到 Ribbon 的重试机制的影响。在默认情况下,Ribbon 会进行 5 次重试,每次重试之间的间隔时间逐渐加长。如果设置了超时时间,但是请求一直被重试,那么可能会导致超时时间被延长,从而影响应用程序的性能和稳定性。
因此,为了更加精确地控制超时时间,并避免受到 Ribbon 的重试机制的影响,建议在 OpenFeign 中设置超时时间。
openFeign 默认使用的是 JDK 原生的 URLConnection 发送 HTTP 请求,没有连接池,但是对每个地址会保持一个长连接,即利用 HTTP 的 persistence connection。在生产环境中,通常不使用默认的 http client,通常有两种选择:使用 ApacheHttpClient 或者 OkHttp,两者各有千秋
修改pom.xml
添加如下依赖
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
dependency>
<dependency>
<groupId>io.github.openfeigngroupId>
<artifactId>feign-httpclientartifactId>
dependency>
openFeign 虽然提供了日志增强功能,但默认是不显示任何日志的,不过开发者在调试阶段可以自己配置日志的级别。
openFeign 的日志级别如下:
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
修改application.yml
添加配置
logging:
level:
# feign日志以什么级别监控哪个接口
com.lufei.springcloud.service: debug