1、簡介
Feign是聲明式的服務調用工具,我們只需創建一個接口並用注解的方式來配置它,就可以實現對某個服務接口的調用,簡化了直接使用RestTemplate來調用服務接口的開發量。Feign具備可插拔的注解支持,同時支持Feign注解、JAX-RS注解及SpringMvc注解。當使用Feign時,Spring Cloud集成了Ribbon和Eureka以提供負載均衡的服務調用及基於Hystrix的服務容錯保護功能。
2、向pom文件中添加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
3、啟動類加上注解
@EnableFeignClients
4、service層
package com.donleo.user.service; import com.donleo.user.common.CommonResult; import com.donleo.user.config.FeignClientConfig; import com.donleo.user.model.Word; import com.donleo.user.service.impl.WordServiceFallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; /** * 聲明式服務調用配置 * .@FeignClient 指定服務 * value 服務名 * fallbackFactory 調用失敗,服務降級返回結果 * configuration 自定義配置 * * @author liangd * @since 2021-01-12 16:18 */ @FeignClient(value = "word-app", fallbackFactory = WordServiceFallbackFactory.class, configuration = FeignClientConfig.class) public interface WordService { /** * 查詢所有 */ @GetMapping("/word/findAll") CommonResult feignFindAllWord(); /** * 單個查詢 */ @GetMapping("/word/findById2") CommonResult feignFindWordById(@RequestParam("id") Integer id); /** * 新增 */ @PostMapping("/word/create") CommonResult feignCreateWord(@RequestBody Word word); /** * 修改 */ @PutMapping("/word/update") CommonResult feignUpdateWord(@RequestBody Word word); /** * 刪除 */ @DeleteMapping("/word/delete") CommonResult feignDeleteWordById(@RequestParam("id") Integer id); }
注意:@RequestParam如果不指定參數名字,可能會報java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0
最好指定參數名字@RequestParam(“id”)
5、controller層測試
controller層調用接口測試
/** * 查詢所有 */ @GetMapping("/feignFindAllWord") public CommonResult feignFindAllWord(){ return wordService.feignFindAllWord(); } /** * 單個 */ @GetMapping("/feignFindWordById") public CommonResult feignFindWordById(@RequestParam Integer id){ return wordService.feignFindWordById(id); } /** * 新增 */ @GetMapping("/feignCreateWord") public CommonResult feignCreateWord(){ Word word = Word.builder().id(101).chinese("自己").english("self").author("liangd").commitTime(new Date()).build(); return wordService.feignCreateWord(word); } /** * 修改 */ @GetMapping("/feignUpdateWord") public CommonResult feignUpdateWord(){ Word word = Word.builder().id(101).chinese("愛好").english("hobby").author("liangd").commitTime(new Date()).build(); return wordService.feignUpdateWord(word); } /** * 刪除 */ @GetMapping("/feignDeleteWordById") public CommonResult feignDeleteWordById(){ Integer id = 101; return wordService.feignDeleteWordById(id); }
6、WordServiceFallbackFactory配置(服務降級)
如果連接超時,可以這里定義數據返回結果
package com.donleo.user.service.impl; import com.donleo.user.common.CommonResult; import com.donleo.user.model.Word; import com.donleo.user.service.WordService; import feign.hystrix.FallbackFactory; import org.springframework.stereotype.Component; /** * FeignClient 調用異常工廠配置類 * 服務降級 * * @author liangd * @since 2021-01-12 17:40 */ @Component public class WordServiceFallbackFactory implements FallbackFactory<WordService> { @Override public WordService create(Throwable throwable) { return new WordService() { @Override public CommonResult feignFindAllWord() { return CommonResult.failed("連接異常"); } @Override public CommonResult feignFindWordById(Integer id) { return CommonResult.failed("連接異常"); } @Override public CommonResult feignCreateWord(Word word) { return CommonResult.failed("連接異常"); } @Override public CommonResult feignUpdateWord(Word word) { return CommonResult.failed("連接異常"); } @Override public CommonResult feignDeleteWordById(Integer id) { return CommonResult.failed("連接異常"); } }; } }
7、FeignClientConfig配置
使用feign調用接口時,默認連接時間是2s,在打斷點調試程序時,如果不指定連接時間和降級處理,就會報錯:Read time out
package com.donleo.user.config; import feign.Logger; import feign.Request; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; /** * FeignClient配置類 * * @author liangd * @since 2021-01-12 17:24 */ @Component public class FeignClientConfig { // 連接超時 @Value("${service.feign.connectTimeout:60000}") private int connectTimeout; // 數據讀取超時 60s @Value("${service.feign.readTimeOut:60000}") private int readTimeout; // 構造自定義連接超時配置類 @Bean public Request.Options options() { return new Request.Options(connectTimeout, readTimeout); } /** * 配置Feign日志 * 日志的四個參數說明: * * NONE:默認的,不顯示任何日志; * BASIC:僅記錄請求方法、URL、響應狀態碼及執行時間; * HEADERS:除了BASIC中定義的信息之外,還有請求和響應的頭信息; * FULL:除了HEADERS中定義的信息之外,還有請求和響應的正文及元數據。 */ @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
feign日志級別說明
- NONE:默認的,不顯示任何日志;
- BASIC:僅記錄請求方法、URL、響應狀態碼及執行時間;
- HEADERS:除了BASIC中定義的信息之外,還有請求和響應的頭信息;
- FULL:除了HEADERS中定義的信息之外,還有請求和響應的正文及元數據。
8、application.yml配置打印日志
#log
logging:
level:
com.donleo.user.mapper: debug
com.donleo.user.service.WordService: debug # 查看Feign日志