本文總結Feign常見問題及解決方案。git
@PathVariable
,必須指定value屬性代碼示例:github
@FeignClient("microservice-provider-user") public interface UserFeignClient { @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET) public User findById(@PathVariable("id") Long id); ... }
其中的@PathVariable("id")
中的」id」,也就是value屬性,必須指定,不能省略。web
詳見:如何使用Feign構造多參數的請求spring
Feign自己已經整合了Hystrix,可直接使用@FeignClient(value = "microservice-provider-user", fallback = XXX.class)
來指定fallback類,fallback類繼承@FeignClient所標註的接口便可。app
可是假設如需使用Hystrix Stream進行監控,默認狀況下,訪問http://IP:PORT/actuator/hystrix.stream
是會返回404,這是由於Feign雖然整合了Hystrix,但並無整合Hystrix的監控。如何添加監控支持呢?須要如下幾步:ide
第一步:添加依賴,示例:ui
<!-- 整合hystrix,其實feign中自帶了hystrix,引入該依賴主要是爲了使用其中的hystrix-metrics-event-stream,用於dashboard --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
第二步:在啓動類上添加@EnableCircuitBreaker
註解,示例:url
@SpringBootApplication @EnableFeignClients @EnableDiscoveryClient @EnableCircuitBreaker public class MovieFeignHystrixApplication { public static void main(String[] args) { SpringApplication.run(MovieFeignHystrixApplication.class, args); } }
第三步:在application.yml中添加以下內容,暴露hystrix.stream端點:code
management: endpoints: web: exposure: include: 'hystrix.stream'
這樣,訪問任意Feign Client接口的API後,再訪問http://IP:PORT/actuator/hystrix.stream
,就會展現一大堆Hystrix監控數據了。繼承
代碼示例:
@FeignClient(name = "microservice-provider-user", configuration = UserFeignConfig.class) public interface UserFeignClient { @GetMapping("/users/{id}") User findById(@PathVariable("id") Long id); } /** * 該Feign Client的配置類,注意: * 1. 該類能夠獨立出去; * 2. 該類上也可添加@Configuration聲明是一個配置類; * 配置類上也可添加@Configuration註解,聲明這是一個配置類; * 但此時千萬別將該放置在主應用程序上下文@ComponentScan所掃描的包中, * 不然,該配置將會被全部Feign Client共享,沒法實現細粒度配置! * 我的建議:像我同樣,不加@Configuration註解 * * @author zhouli */ class UserFeignConfig { @Bean public Logger.Level logger() { return Logger.Level.FULL; } }
@Configuraiton
註解,聲明這是一個配置類;但此時千萬別將該放置在主應用程序上下文@ComponentScan
所掃描的包中,不然,該配置將會被全部Feign Client共享(至關於變成了通用配置,其實本質仍是Spring父子上下文掃描包重疊致使的問題),沒法實現細粒度配置!詳見:Spring Cloud中,如何解決Feign/Ribbon第一次請求失敗的問題?
@FeignClient
註解屬性@FeignClient(name = "microservice-provider-user")
在早期的Spring Cloud版本中,無需提供name屬性,從Brixton版開始,@FeignClient必須提供name屬性,不然應用將沒法正常啓動!
另外,name、url等屬性支持佔位符。例如:
@FeignClient(name = "${feign.name}", url = "${feign.url}")
@RequestMapping("/users") @FeignClient(name = "microservice-user") public class TestFeignClient { // ... }
類上的@RequestMapping
註解也會被Spring MVC加載。該問題現已經被解決,早期的版本有兩種解決方案:
方案1:不在類上加@RequestMapping
註解;
方案2:添加以下代碼:
@Configuration @ConditionalOnClass({ Feign.class }) public class FeignMappingDefaultConfiguration { @Bean public WebMvcRegistrations feignWebRegistrations() { return new WebMvcRegistrationsAdapter() { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new FeignFilterRequestMappingHandlerMapping(); } }; } private static class FeignFilterRequestMappingHandlerMapping extends RequestMappingHandlerMapping { @Override protected boolean isHandler(Class<?> beanType) { return super.isHandler(beanType) && !beanType.isInterface(); } } }
相關Issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/466
http://www.itmuch.com/spring-cloud/finchley-11/