基本介绍
Feign 是Spring Cloud Netflix项目中的HTTP服务客户端,支持ReST准则和SOAP协议,实现了负载均衡和 Rest 调用的开源框架,封装了Ribbon和RestTemplate, 实现了WebService的面向接口编程,旨在降低http调用的复杂度,减少调用开销和简化代码。
为了方便使用,SpringCloud开发OpenFeign作为第二代客户端集成了Ribbon或LoadBalancer,在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。
组件支持
简单应用
- 注解
Annotation | Interface Target | Usage |
---|---|---|
@RequestLine |
Method | 定义请求,支持表达式值映射,{expression} 解析为@Param 对应变量 |
@Param |
Parameter | 定义模板变量,参数名对应注解提供的名称 |
@Headers |
Method, Type | 定义请求头 支持表达式值映射,{expression} 解析为@Param 对应变量 |
@QueryMap /@SpringQueryMap |
Parameter | 定义请求参数Map,后者为OpenFeign提供支持Spring的Map注解 |
@HeaderMap |
Parameter | 定义请求头Map,将扩展到请求头 |
@Body |
Method | 定义一个请求体,支持表达式值映射,如xml、json表达式 |
- Feign客户端
声明式接口调用 Feign通过使用Java接口的方式,让我们可以轻松地声明需要调用的远程接口。无需编写繁琐的HTTP请求代码,我们只需定义一个接口,并在方法上添加注解来标识请求的URL、HTTP方法、请求参数等信息。Feign集成了负载均衡的功能,可以与服务注册中心(如Eureka)进行集成,自动实现服务的发现与负载均衡。这意味着我们可以通过Feign调用任何可用的服务,而无需关心具体的服务实例。
@FeignClient(contextId = "remoteUserService", value = "cloud-system", fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService {
@GetMapping(value = "/user/getUserInfo",)
Response<List<UserInfo>> getUserInfo(@RequestParam("userId") int userId);
@RequestMapping(value = "/user/addUserInfo", method = RequestMethod.POST)
Response<String> addUserInfo(@RequestBody("userInfo") UserInfo userInfo);
}
- 拦截器
Feign提供了很多配置选项,可以满足我们对接口调用的各种需求。我们可以通过自定义Feign的配置类来进行定制,例如修改请求头、添加拦截器等。
//请求拦截器
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
Map<String, String> headers = getHeaders();
headers.forEach(template::header);
}
}
//响应拦截器
public class CustomResponseInterceptor implements ResponseInterceptor {
@Override
public void interceptResponse(Response response) {
if (response.status() == 401) {
throw new UnauthorizedException();
}
}
}
/********************************************************************/
// 局部拦截器注册
@FeignClient(name = "gateway", configuration = FeignInterceptor.class, fallbackFactory = RemoteUserFallbackFactory.class)
// 全局拦截器注册
@Configuration
public class FeignConfig {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("fox", "123456");
}
}
- 异常处理机制
@Slf4j
public class OpenFeignErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
log.error("feign client error,response is {}:",response);
return new BusinessException("Feign client 调用异常");
}
}
- 超时与重试机制
在网络通信中,不可避免地会出现请求超时或异常的情况。Feign提供了超时和重试的机制,允许我们设置请求的超时时间,并在请求失败时进行重试,提高了调用的可靠性。
public class MyRetryer implements Retryer {
@Override
public void continueOrPropagate(RetryableException e) {
throw e;
}
@Override
public Retryer clone() {
return new Default(100, TimeUnit.SECONDS.toMillis(1), 5);
// period:周期,重试间隔时间
//maxPeriod:最大周期,重试间隔时间按照一定的规则逐渐增大,但不能超过最大周期
//maxAttempts:最大尝试次数,重试次数
}
}
总结
Feign作为一个简单易用的HTTP客户端工具,为我们的服务间通信提供了便利。通过其声明式的接口调用、自动序列化与反序列化、负载均衡与服务发现、超时与重试机制以及易于扩展和定制等特性,我们可以更加轻松地实现接口调用的功能。