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日志