11.OpenFeign服务接口调用
OpenFeign是什么?
1.Feign是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
2.Feign旨在使编写Java Http客户端变得更容易。
3.前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。
但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,
所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。
所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。
在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),
即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
openfeign与feign区别:
openfign
|
feign
|
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
|
OpenFeign是Spring Cloud 在Feign的基础上支持了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
|
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
|
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
|
spring cloud整合openfeign
1.新建cloud-consumer-feign-order80模块
2.修改pom文件,添加以下依赖。
<dependencies>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--一般基础通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.com.springcloud</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
3.添加配置文件application.yml
server:
port: 80
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
#defaultZone: http://localhost:7001/eureka
# 集群版
defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
instance:
instance-id: feign-userConsumer80
prefer-ip-address: true
spring:
application:
name: feign-customer-user
4.springboot启动类代码:(重点1:@EnableFeignClients标签的使用,开启openfeign)
@SpringBootApplication
//重点1:@EnableFeignClients标签的使用,开启openfeign
@EnableFeignClients
public class FeigbApplication80 {
public static void main(String[] args) {
SpringApplication.run(FeigbApplication80.class,args);
}
}
5.写接口代码(重要点2:@FeignClient("PRODUCER-USER-API")绑定远程服务端的对外能力)
解释:绑定服务提供端的请求
原理:当控制层调用该接口的queryUserById方法时,会去eureka的注册中心找到PRODUCER-USER-API的服务,
然后调用拼接/producer/queryUserById/{id}的路径,即调用的是服务端/producer/queryUserById/{id}的方法
@FeignClient("PRODUCER-USER-API")
@Component
public interface FeignService {
@GetMapping("/producer/queryUserById/{id}")
public CommResult queryUserById(@PathVariable("id") int id);
}
原理解释:
1.在springboot启动类上加上@EnableFeignClients注解,开启OpenFeign功能
2.在接口上加上注解@FeignClient("PRODUCER-USER-API")绑定远程服务
3.当请求http://localhost/feign/queryUserById/6时,会调用到该接口上,openFeign会先根据@FeignClient注解找到远程服务
在调用远程服务的/producer/queryUserById/{id}请求并返回
如图所示:openfeign的包里包含了ribbon的包,所以openfeign本身具有负载均衡的能力,默认是轮询!
OpenFeign超时控制
openfeign如果调用远程服务超时怎么办?openfeign底层是ribbion调用远程,ribbon远程调用超时时间默认是1秒钟
如果故意在服务侧线程休眠导致超时,调用会报错!
可以看到报错了,报的是超时异常。
有时我们处理业务的时间超过了1s,所以我们要设置一下超时等待的时间。
在applicaiton.yml中进行配置:
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
openfeign的日志级别
如果openfeign经常性调用,想查看openfeign发送的到底是什么东西,可以配置openfeign的日志级别!
级别
1.NONE:默认,不显示任何日志
2.BASIC:仅记录请求方法、URL、响应状态码及执行时间等
3.HEADERS:除了BASIC中定义的信息外,还有请求和响应的头信息
4.FULL:除了HEADERS中定义的信息外,还有请求和响应的正问和元数据等
做法:
1.写个自己的配置类:
@Configuration
public class Myconfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
2.application.yml中配置
logging:
level:
# feign日志以什么级别监控哪个接口
cn.com.cloud.feignConsumer.service.FeignService : debug
3. 控制台输出:
: [FeignService#queryUserById] <--- HTTP/1.1 200 (391ms)
: [FeignService#queryUserById] connection: keep-alive
: [FeignService#queryUserById] content-type: application/json
: [FeignService#queryUserById] date: Mon, 19 Jul 2021 09:29:29 GMT
: [FeignService#queryUserById] keep-alive: timeout=60
: [FeignService#queryUserById] transfer-encoding: chunked
: [FeignService#queryUserById]
: [FeignService#queryUserById] {"status":200,"message":"成功!serverPort:8001","result":{"id":6,"name":"吴孟达","pwd":"123123"}}
: [FeignService#queryUserById] <--- END HTTP (101-byte body)