SpringCloud客户端调用工具之【Feign客户端工具的使用】

前言

  虽然此篇文章介绍Feign客户端调用工具,但是我们也要知道SpringCloud 中支持两种客户端调用工具: ①RestTemplate(基本上不用)、②Feign客户端工具(项目开发中用的较多)。这篇文章重点介绍Feign客户端的调用工具的使用方法。

  Feign是一个声明式得Http客户端调用工具,采用接口+注解方式实现,易读性较强。主要基于两个注解实现:@EnableFeignClients和@FeignClient,下边具体步骤详细介绍这两个注解的使用方法与参数定义。

接下来,我以近期项目开发中利用Feign客户端工具进行RPC调用,从头搭建整个服务的调用过程,以及接口规范化的书写,尽量贴合实际的项目开发规范,毕竟良好的代码书写规范是很值得Leader的青睐。

1、pom.xml文件需引入对应的jar包
基于SpringCloud开发环境,只列入相关jar包

	 <!-- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
     <!--Feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、application.yml的配置文件

### 服务端口
server:
  port: 7878
###定义服务名称
spring:
  application:
    name: server1
# Eureka注册中心
eureka:
  instance:
    hostname: 127.0.0.1
    instance-id: ${spring.application.name}:${eureka.instance.hostname}:${server.port}
  client:
    service-url:
      defaultZone: http://127.0.0.1:9999/bureka
    register-with-eureka: true
    fetch-registry: true
spring:
  datasource:
    # 数据源1
    his:
      username: root
      password: 123
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
  redis:
    host: 127.0.0.1

3、Feign声明接口的编写
  前面我们提到Feign是一个声明式得Http客户端调用工具,采用接口+注解方式实现,核心注解为 @FeignClient注解,接下来重点介绍下此注解。
FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上,源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
    @AliasFor("name")
    String value() default "";
    /** @deprecated */
    @Deprecated
    String serviceId() default "";
    @AliasFor("value")
    String name() default "";
    String qualifier() default "";
    String url() default "";
    boolean decode404() default false;
    Class<?>[] configuration() default {};
    Class<?> fallback() default void.class;
    Class<?> fallbackFactory() default void.class;
    String path() default "";
    boolean primary() default true;
}

声明接口之后,在代码中通过@Autowired注入即可应用。@FeignClient标签的常用属性如下:

  • value: 是服务提供方在eureka注册的名字
  • name: 指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
  • url: 一般用于调试,可以手动指定@FeignClient调用的地址
  • decode404: 当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口;
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀

插入Feign请求超时问题
  Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。而首次请求往往会比较慢(因为Spring的懒加载机制,要实例化一些类),这个响应时间可能就大于1秒了
解决方案有三种,以feign为例。
方法一
  hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
该配置是让Hystrix的超时时间改为5秒
方法二
  hystrix.command.default.execution.timeout.enabled: false
该配置,用于禁用Hystrix的超时时间
方法三
  feign.hystrix.enabled: false
该配置,用于索性禁用feign的hystrix。该做法除非一些特殊场景,不推荐使用。

项目的实际运用:
  比如我们的项目中,一个数据中心服务,一个是同步服务,数据中心服务已经写好了所有跟第三方调用的接口。同步服务只需要按照数据中心提供的接口文档,书写对应的接口。最后将这两个服务统一注册到Eureka注册中心,通过Feign客户端调用工具实现RPC远程调用。
规范书写,紧贴实际开发需求,延展性和可扩展性强

@FeignClient(value = "server", path = "/serverPath", url = "127.0.0.1:8899")
public interface FeignClientIn {
    @ApiOperation(value = "获取服务接口一")
    @GetMapping("/serverOne")
    FeignResponse<List<user>> getUserInfo(@RequestParam("name") String name);
    
    @ApiOperation(value = "获取服务接口二")
    @GetMapping("/serverTwo")
    FeignResponse<List<Order>> getOrderInfo(@RequestParam("age") String age);
 }                                      

全局API接口返回的FeignResponse类

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
public class FeignResponse<T>{
    @ApiModelProperty(value = "状态码,成功为2000", example = "2000")
    private int code;
    @ApiModelProperty(value = "成功标识", example = "true")
    private boolean success;
    @ApiModelProperty(value = "状态码为2000时,msg为OK, 否则为错误提示信息", example = "OK")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private T data;
    @ApiModelProperty(value = "时间戳", example = "1554787157007")
    private long timestamp;
}

4、启动类

@EnableEurekaClient
@EnableFeignClients("com.lbn.generic.feign")  //启用feign客户端
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }
}
发布了34 篇原创文章 · 获赞 44 · 访问量 9080

猜你喜欢

转载自blog.csdn.net/qq_41144667/article/details/104432421