整合 Spring Cloud OpenFeign
OpenFeign
Feign
- 官网 https://github.com/OpenFeign/feign
- Feign是一个受到Retrofit,JAXRS-2.0和WebSocket启发的Java到HTTP客户端绑定器。
- Feign的第一个目标是降低将Denominator统一绑定到HTTP API 的复杂性。相当于,OpenFeign将HTTP服务之间的请求由传统的HTTP API调用IP完整路径替换成模块化访问,降低复杂度
Spring Cloud OpenFeign
Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。
我们知道,前端访问后端微服务接口时,都是通过:“ip+端口+接口api”的形式进行调用的,而有时候我们访问一个服务的接口,该接口业务可能还会内部调用另一个微服务的接口进行信息处理,而这时候采用硬编码方式即使用IP+端口方式调用则会显得十分僵硬和不方便。
结合SpringCloud后,由于存在注册中心,每个服务都会在注册中心进行注册,所以Spring Cloud OpenFeign实现了通过注册服务模块进行特定服务访问的方式,方便了服务间调用的简化
原理
整合Spring Cloud Feign
引依赖。新建一个测试项目:springcloud-client2,并引入依赖
1
2
3
4
5
6
7
8
9<!--feign 依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>加配置,将该模块服务注册在eureka中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21server:
port: 7920 #服务端口
spring:
profiles:
active: 700 #当前生效环境
application:
name: springcloud-client2 #指定应用的唯一标识/服务名
# 配置中心
cloud:
config:
fail-fast: true
name: ${spring.application.name},datasource,redis #指定工程于config server中的应用名
profile: ${spring.profiles.active} #指定工程于config server中的生效环境
uri: http://localhost:8080 #指定配置中心的注册路径
# 注册中心配置
eureka:
instance:
prefer-ip-address: true #优先使用IP地址注册
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/ #eureka的注册地址加注解,启动类使用@EnableFeignClient 注解开启Feign服务
1
2
3
4
5
6
7
8
public class SpringCloudClient2Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloudClient2Application.class, args);
}
}编写一个FeignClient
@FeignClient("provider微服务名字")
- 如果需要传递参数,那么@RequestParam 和@RequestBody @PathVariable 不能省,必加
1
2
3
4
5
6
7
8
9
10//指向注册名为springcloud-client的服务
public interface TestFeignIntercept {
/**
* 内部接口,获取信息
* @return
*/
//指向springcloud-client中接口路径为/feign/test的接口
Map getFeignMassage(; Long id)
}同时,在springcloud-client服务工程中编写接口路径为/test/feign的接口,供内部调用
1
2
3
4
5
6
7
8
9
10
11
12
public class FeignTestController {
public Map getUser( { Long id)
Map result = new HashMap();
result.put("id", id);
result.put("name", "xiaoming");
result.put("sex", "male");
result.put("age", 12);
return result;
}
}编写接口调用FeignClient实现内部访问
@FeignClient("springcloud-client")
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TestFeignController {
private TestFeignIntercept testFeignIntercept;
/**
* 获取信息
* @return
*/
public Map getFeignMessage({ Long id)
return this.testFeignIntercept.getFeignMassage(id);
}
}启动Eureka,Config,client,Client2服务, 调用springcloud-client2的 /testFeign 接口:
OpenFeign超时控制
演示超时出错
超时设置,故意设置超时演示出错情况
1
2
3
4
5
6
7
8
9
10
11
public Map getUser( Long id)throws InterruptedException {
// 服务提供方8001故意写暂停程序
Thread.sleep(3000);
Map result = new HashMap();
result.put("id", id);
result.put("name", "xiaoming");
result.put("sex", "male");
result.put("age", 12);
return result;
}
超时控制
默认Feign客户端只等待一秒钟,但是服务段处理需要超过1秒钟,导致Feign客户端不想等待了,直接返回报错。
为了避免这种请况,有时候我们需要设置Feign客户端的超时控制
Feign 默认是支持Ribbon ,Feign依赖里自己带了Ribbon
在消费端的配置文件中配置
- 这里的ReadTimeout 和 ConnectTimeout 没有代码提示,但可以使用
1
2
3
4
5
6# 设置feign 客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 设置建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
# 设置建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
OpenFeign日志打印
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。
说白了就是:对Feign接口的调用情况进行监控和输出。
日志级别 说明 NONE 默认的,不显示任何日志 BASIC 仅记录请求方法、URL、响应状态码及执行时间 HEADERS 除了BASIC中定义的信息之外,还有请求和响应的头信息 FULL 除了HEADERS中定义的信息外,还有请求和响应的正文及元数据。
消费端配置日志
配置日志bean
1
2
3
4
5
6
7
8
9import feign.Logger;
import org.springframework.context.annotation.Bean;
public class FeignConfig {
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}配置文件
1
2
3
4logging:
level:
# feign 日志以什么级别监控哪个接口
pers.fulsun.demo.springcloud.controller.TestFeignIntercept: debug