2021-03-17 记录openFeign的使用

前言:

        新公司的项目中,服务之间的调用用到了 spring cloud 的 openfeign组件;虽然之前有自己学习过一些spring cloud组件使用,但是时间长了,记忆也模糊了,所以今天决定在博客上面记录下今天使用openFegin遇到的问题,防止日后又忘记了。

openFegin简介:

     spring cloud 将openFeign集成到spring boot应用中,为微服务之间的相互调用提供了解决方案,最开始是利用openFeign的声明式方式定义wed客户端,再之后通过Ribbon和Eureka实现负载均衡的HTTP客户端;openFeigns是一个声明式,模块化的HTTP客户端,可以实现调用远程接口如调用方法一样简单。

openFegin的注解介绍:

    1. @FeginClient // 标注在接口上声明该接口为Fegin客户端  fallback容错类需要标注@Component,否则运行时无法注册容错类 

@Target({ElementType.TYPE})                 
@Retention(RetentionPolicy.RUNTIME)        
@Documented
@Inherited
public @interface FeignClient {
    @AliasFor("name")
    String value() default "";

    /** @deprecated */
    @Deprecated
    String serviceId() default "";
    
    // 标注上下文的名称
    String contextId() default "";
    
    //指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
    @AliasFor("value")
    String name() default "";            

    String qualifier() default "";
    
    // url一般用于调试,可以手动指定@FeignClient调用的地址
    String url() default "";
    
    // 当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
    boolean decode404() default false;

    // Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
    Class<?>[] configuration() default {};

    // 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的 
       类必须实现@FeignClient标记的接口
    Class<?> fallback() default void.class;
    
    // 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重 
       复的代码
    Class<?> fallbackFactory() default void.class;
    
    // 定义当前FeignClient的统一前缀
    String path() default "";

    boolean primary() default true;
}

     2.@EnableFeginClients    // 标注在Spring boot应用入口上开启一个Fegin客户端

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
// FeignClientsRegistrar 实现了 ImportBeanDefinitionRegistrar 接口 该接口是注册Feign客服的
@Import({FeignClientsRegistrar.class})    
public @interface EnableFeignClients {
    
    String[] value() default {};
    
    // 可以指定扫描包的路径
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
    
    // 指定默认的配置类 
    Class<?>[] defaultConfiguration() default {};
    
    // 指定Feign客户端
    Class<?>[] clients() default {};
}

使用openFeign注意事项:

    1.在FeignClient中参数只能有一个@RequestBody 注解多个@RequestParam 注解接收参数。

    2.FeignClient无法直接传递HttpServletRequest request,如需要传递request获取头部参数信息,可以去实现Fegin的RequestInterceptor拦截器,原因好像是因为Feign发送请求的时候是另外一条线程去去处理,所以服务器接收到的request是另外的一个Request, 实现Fegin的拦截器代码如下:

/**
 * @author CJL
 * @description: Fegin拦截器 设置所有的请求头信息
 * @date 2021/3/17
 */
@Component
public class FeginRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            Enumeration<String> headerNames = request.getHeaderNames();
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String key = headerNames.nextElement();
                    String value = request.getHeader(key);
                    if (key.equalsIgnoreCase("content-length")){
                        continue;
                    }
                    requestTemplate.header(key,value);
                }
            }
        }
    }
}

需要注意的是服务相互调用的时间的控制,太短的话可能出现时间超时的问题,可以根据实际情况在配置文件中配置调用查询的时间:

feign:
  hystrix:
    enabled: false
  client:
    config:
      default:
        connectTimeout: 30000 #单位毫秒
        readTimeout: 30000 #单位毫秒

在@FeignClient 客户端中可以通过 configuration 单独配置该客户端的请求拦截器,已达到实现我们想要的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值