微服务SpringCloud Alibaba ------(六)OpenFeign

1. 什么是Feign

Feign是Ntlix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、 JAXRS-2.0以及WebSocket. Feign可帮助我们更加便捷、优雅地调用HTTP API。
Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便

1.1优势

Feign可以做到使用HTTP请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。它像Dubbo-样, consumer 直接调用接口方法调用provider,而不需要通过常规的Http Client构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法-样,无需关注与远程的交互细节,更无需关注分布式环境开发。

2. Spring Cloud Alibaba 整合 OpenFeign

2.1. 第一步

添加依赖

<!--第一步、添加openfeign依赖、版本在pom.xml中的dependencyManagement已经管理-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2. 第二步

创建接口

// 第二步、增加feign接口和方法
// name = 服务名称 / path = Controller类ReqeustMapper
@FeignClient(name = "stock-service",path = "/stock")
public interface StockFeignService {
    
    

  // 声明需要调用的rest接口对应的方法
  @RequestMapping("/reduct")
  public String reduct();

}
/** 
 * 对应的服务接口
 @RestController
 @RequestMapping("/stock")
 @Slf4j
 public class StockController {

	 @Value("${server.port}")
	 private String port;
	
	 @RequestMapping("/reduct")
	 public String reduct(){
		 log.debug("扣减库存!");
		 return "扣减库存成功!端口:" + port;
	 }

 }
 */

2.3. 第三步

注入接口并调用方法

// 第三步、注入feign接口,并调用方法
@Resource
private StockFeignService stockFeignService;

// 调用方法
String result = stockFeignService.reduct();

2.4. 第四步

启动类添加注解启用feign客户端

@SpringBootApplication
//Spring Cloud 原生注解 ,开启服务注册发现功能
@EnableDiscoveryClient
// 第四步、添加注解启用feign客户端
@EnableFeignClients
public class OrderApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run( OrderApplication.class, args );
    }

}

3. OpenFeign自定义配置及使用

3.1. 日志配置

有时候遇到BUG,比如接口调用失败、参数没收到等问题或者查看调用性能,可以通过配置日志来把请求信息输出出来

3.1.1. 通过配置类指定日志级别

通过源码可以看到日志等级有4种,分别是:

  • NONE [性能最佳,适用于生产] :不记录任何日志(默认值)。
  • BASIC [适用于生产环境追踪问题] :仅记录请求方法、URL、 响应状态代码以及执行时间。
  • HEADER:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL [比较适用于开发及测试环境定位问题] :记录请求和响应的header、body和元数据。

/**
 * feign配置类
 * @Author Xxx
 * @Date 2021/11/22 15:20
 * @Version 1.0
 */
// 全局配置 当使用@Configuration,会将配置作用所有的服务提供方
// 局部配置 如果只想针对某一个服务配置,不要加@Configuration,可以采用配置类或者配置文件
//@Configuration
public class FeignConfig {
    
    

    @Bean
    public Logger.Level feignLoggerLevel(){
    
    
        /**
         - NONE [性能最佳,适用于生产] :不记录任何日志(==默认值==)。
         - BASIC [适用于生产环境追踪问题] :仅记录请求方法、URL、 响应状态代码以及执行时间。
         - HEADER:记录BASIC级别的基础上,记录请求和响应的header。
         - FULL [比较适用于开发及测试环境定位问题] :记录请求和响应的header、body和元数据。
         */
        return Logger.Level.FULL;
    }
}
//局部配置时通过configuration属性
@FeignClient(name = "stock-service", path = "/stock", configuration = FeignConfig.class)

3.1.2. 通过配置文件指定日志级别

# feign日志局部配置
feign:
  client:
    config:
      product-service: # 服务名称
        loggerLevel: BASIC # 日志级别

3.2. 契约配置

Spring Cloud在Feign的基础上做了扩展,使用Spring MVC的注解来完成Feign的功能。原生的Feign是不支持Spring MVC注解的,如果你想在Spring Cloud中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud中默认的是SpringMvcContract。

Spring Cloud 1 早期版本就是用的远程Feign,随着netflix的停更替换成了OpenFeign。

通常用于版本升级保留原生注解

3.2.1. 通过配置类

// 全局配置 当使用@Configuration,会将配置作用所有的服务提供方
// 局部配置 如果只想针对某一个服务配置,不要加@Configuration,可以采用配置类或者配置文件
//@Configuration
public class FeignConfig {
    
    
     //修改契约配置,支持Feign原生的注解
    @Bean
    public Contract feignContract(){
    
    
        return new Contract.Default();
    }
}
//局部配置时通过configuration属性
@FeignClient(name = "stock-service", path = "/stock", configuration = FeignConfig.class)

3.2.2. 通过配置文件

# feign日志局部配置
feign:
  client:
    config:
      product-service: # 服务名称
        contract: feign.Contract.Default #设置为默认的契约,还原成原生注解

3.3. 超时时间配置

3.3.1. 通过配置类

// 全局配置 当使用@Configuration,会将配置作用所有的服务提供方
// 局部配置 如果只想针对某一个服务配置,不要加@Configuration,可以采用配置类或者配置文件
//@Configuration
public class FeignConfig {
    
    
    /**
     * 设置超时时间
     */
     @Bean
    public Request.Options options(){
    
    
        return new Request.Options(5000, TimeUnit.MILLISECONDS, 10000, TimeUnit.MILLISECONDS, true);
    }
}

3.3.2. 通过配置文件

# feign日志局部配置
feign:
  client:
    config:
      product-service: # 服务名称
        # 连接超时时间
        connectTimeout: 5000
        # 请求处理超时时间
        readTimeout: 10000

3.4. 自定义拦截器

3.4.1. 通过配置类

/**
 * @Author Xxx
 * @Date 2021/11/22 16:48
 * @Version 1.0
 */
@Slf4j
public class FeignAuthRequestInterceptor implements RequestInterceptor {
    
    

    public void apply(RequestTemplate template) {
    
    
        String token = UUID.randomUUID().toString();
        log.debug("feign拦截器!");
        template.header("Authorization", token);
    }

}



// 全局配置 当使用@Configuration,会将配置作用所有的服务提供方
// 局部配置 如果只想针对某一个服务配置,不要加@Configuration,可以采用配置类或者配置文件
//@Configuration
public class FeignConfig {
    
    
	/**
     * 配置拦截器
     */
    @Bean
    public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){
    
    
        return new FeignAuthRequestInterceptor();
    }
}

3.4.2. 通过配置文件

# feign日志局部配置
feign:
  client:
    config:
      product-service: # 服务名称
        requestInterceptors[0]: 拦截器全包名

猜你喜欢

转载自blog.csdn.net/qq_42017523/article/details/121471333