Feign简介

  1. Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便,
  2. 要使用Feign创建一个界面并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。
  3. Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,
  4. 并使用Spring Web中默认使用的HttpMessageConverters
  5. Spring Cloud集成RibbonEureka以在使用Feign时提供负载均衡的http客户端。

Feign使用

pom依赖

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

application.yml

server:
  port: 9095
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://root:123456@localhost:10000/eureka/

启动类添加注解

@EnableEurekaClient
@EnableFeignClients  //使用Feign
@SpringBootApplication
public class FeignApplication {
    public static void main(String[] args) {SpringApplication.run(FeignApplication.class, args);}
}

新建接口

@FeignClient("provider") //添加服务提供者的项目名
public interface IFeignClient {

    @GetMapping("/user/{id}") //get请求
    User getUser(@PathVariable("id") Long id);

    @PostMapping("/getuserpojo") //传输复杂对象时,需要post请求
    User getUserPojo(User user);

}

新建controller

@RestController
public class FeignController {

    @Autowired
    private IFeignClient feignClient;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id){
        return feignClient.getUser(id);
    }

    @GetMapping("/getuserpojo")
    public User getUserPojo(User user){
        return feignClient.getUserPojo(user);
    }

}

服务提供者controller

@RestController
public class ProviderController {
    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id){
        return new User(id);
    }

    //这里要post请求,与调用端一致,因为是传输复杂对象,并且需要加上@RequestBody
    @RequestMapping(value = "/getuserpojo",method = RequestMethod.POST)
    public User getUserPojo(@RequestBody User user){
        //返回传过来的user
        return user;
    }
}

启动测试

1.启动EurekaServer
2.启动服务提供者,注册到Eureka
3.启动消费者,测试controller,测试调用服务提供者
里面的user信息,是在服务提供者里写死的。

image.png
image.png

自定义配置Feign

在FeignClient注解上加上configuration参数并制定配置类
@FeignClient(name = "stores", configuration = FeignConfig.class)

也可以使用占位符来读取yml文件
@FeignClient(name = "${feign.name}", url = "${feign.url}")

这个配置类,和ribbon一样,不能被扫描到,所以放到另外的包里。

配置类

image.png

@Configuration
public class FeignConfig {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}

IFeignClient接口

//指定服务名,指定配置类
@FeignClient(name = "provider",configuration = FeignConfig.class)
public interface IFeignClient {

        //可改用Feign提供的@RequestLine组合注解
    @RequestLine("GET /user/{id}") //组合注解,第一个是请求方式,第二个是参数,用空格分割
    User getUser(@Param("id") Long id);//此处@PathVariable注解需要改成@Param注解,否则报错

    @RequestLine("POST /getuserpojo")
    User getUserPojo( User user);

}

Feign日志记录

为每个创建的Feign客户端创建一个记录器。默认情况下,记录器的名称是用于创建Feign客户端的接口的完整类名。
Feign日志记录仅响应DEBUG级别。

application.yml

server:
  port: 9095
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://root:123456@localhost:10000/eureka/
logging:
  level:
    #给指定的FeignClient接口设置日志输出级别,只有debug才会打印日志
    com.springcloud.feign.feignclient.IFeignClient: DEBUG

配置类

import feign.Logger; /这里导入的是feign的logger

@Configuration
public class FeignConfig {

    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    // 配置日志输出
    // NONE :不记录任何日志(默认)
    // BASIC:仅记录请求方法、URL、响应状态代码以及执行时间
    // HEADERS:记录BASIC级别的基础上,记录请求和响应的header
    // FULL:记录请求和响应的header,body和元数据
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

Feign超时设置

application.yml
#全局配置
#Feign 的负载均衡底层用的就是 Ribbon
#ribbon的超时时间
ribbon:
  ReadTimeout: 3000
  ConnectTimeout: 3000