layout: post title: "SpringCloud微服务架构之feign客户端" categories: SpringCloud tags: feign http
Feign是一种声明式、模板化的 HTTP 客户端,在 Spring Cloud 中使用 Feign 其实就是创建一个接口类,它跟普通接口没啥两让,因此通过 Feign 调用 HTTP 请求,开发者完全感知不到这是远程方法。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
@FeignClient(value = FeignConst.COUPON_PROVIDER, url = "${feign.coupon.url:}")
public interface CouponClient {
@GetMapping(value = "/coupon/list/page", headers = LocalsEncoder.CONTENT_TYPE_LOCALS_GET)
RestResponse couponList(@ModelAttribute CouponCriteria criteria);
}
@EnableFeignClients(basePackages = {"com.objcoding"})
@SpringCloudApplication
public class ProviderApplication {
}
当网络不稳定时,一个接口响应非常慢,就会一直占用这个连接资源,如果长时间不做处理,会导致系统雪崩,幸好,Feign 已经继承了熔断器 Hystrix
@FeignClient(value = FeignConst.COUPON_PROVIDER, url = "${feign.coupon.url:}", fallback = CouponClient.CouponClientFallBack.class)
public interface CouponClient {
@GetMapping(value = "/coupon/list/page", headers = LocalsEncoder.CONTENT_TYPE_LOCALS_GET)
RestResponse couponList(@ModelAttribute CouponCriteria criteria);
@Component
class CouponClientFallBack implements CouponClient {
@Override
public RestResponse couponList(CouponCriteria criteria) {
return RestResponse.failed("网络超时");
}
}
}
有时候微服务间的调用,需要传递权限信息,这些信息都包含在请求头了,这时我们可以通过 Feign 拦截器实现权限穿透:
@Configuration
public class WebRequestInterceptor {
@Bean
public RequestInterceptor headerInterceptor() {
return template -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
template.header(name, values);
}
}
};
}
}