SpringCloud(5) ------>Openfeign声明式服务调用接口与服务降级

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日志
原文地址:https://www.cnblogs.com/donleo123/p/14270645.html