目录 Feign 介绍 入门案例 消费端引入 Feign 依赖 编写 Feign 调用接口 Controller 服务调用 启动类添加 Feign 注解 Feign 超时配置 Feign 日志记录 设置日志级别 定义 Feign 的日志级别 Bean 启用该
- Feign 介绍
- 入门案例
- 消费端引入 Feign 依赖
- 编写 Feign 调用接口
- Controller 服务调用
- 启动类添加 Feign 注解
- Feign 超时配置
- Feign 日志记录
- 设置日志级别
- 定义 Feign 的日志级别 Bean
- 启用该 Bean
Feign 介绍
- Feign 是一个声明式的 REST 客户端,它用了基于接口的注解方式,可以很方便地实现客户端配置。
- Feign 最初由 Netflix 公司提供,但最初不支持 SpringMVC 注解,后由 SpringCloud 对其封装,才支持了 SpringMVC 注解,让使用者更易于接受。
- Feign 底层依赖于 Ribbon 实现负载均衡和远程调用。
入门案例 消费端引入 Feign 依赖
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
编写 Feign 调用接口
package com.feign;
import com.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
*
* feign声明式接口:用于发起远程调用
*
* 1. 定义接口
* 2. 接口上添加注解 @FeignClient,并设置 value 属性为服务提供者的应用名称
* 3. 编写调用接口,接口的声明规则和提供方接口保持一致(返回值和方法名可自定义)
* 4. 注入该接口对象,调用接口方法完成远程调用(自动拼接value与接口URI)
*/
@FeignClient(value="eureka-provider")
public interface GoodsFeignClient {
@GetMapping("/goods/findOne/{id}")
public Goods findGoodsById(@PathVariable("id") int id);
}
Controller 服务调用
package com.controller;
import com.domain.Goods;
import com.feign.GoodsFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* 服务调用方
*/
@RestController
@RequestMapping("/order")
public class OrderController {
// @Autowired
// private RestTemplate restTemplate;
@Autowired
private GoodsFeignClient goodsFeignClient; // IDEA 提示报错也无需理会
@GetMapping("/goods/{id}")
public Goods findOrderByGoodsId(@PathVariable("id") int id) {
// String url = String.format("http://eureka-provider/goods/findOne/%d", id);
// Goods goods = restTemplate.getForObject(url, Goods.class);
Goods goods = goodsFeignClient.findGoodsById(id);
return goods;
}
}
启动类添加 Feign 注解
package com;
import com.config.MyRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDiscoveryClient // 激活 DiscoveryClient
@EnableEurekaClient
@SpringBootApplication
@RibbonClient(name="eureka-provider", configuration= MyRule.class) // 指定服务提供方并配置负载均衡策略
@EnableFeignClients // 开启 Feign 功能
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
Feign 超时配置
-
Ribbon默认 1 秒超时。
-
超时配置修改如下:
# 配置消费端 Ribbon 的超时时间
ribbon:
ConnectTimeout: 1000 # 连接超时时间,默认 1s(默认单位毫秒)
ReadTimeout: 3000 # 逻辑处理的超时时间,默认 1s(默认单位毫秒)
Feign 日志记录
Feign 只能记录 debug 级别的日志信息。
设置日志级别消费端 application.yml:
# 设置当前的日志级别 debug(feign 只支持记录 debug 级别的日志)
logging:
level:
com: debug # 指定包名或类名的日志级别
定义 Feign 的日志级别 Bean
package com.consumer.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignLogConfig {
/*
NONE:不记录
BASIC:记录基本的请求行、响应状态码等日志信息
HEADERS:记录基本的请求行、响应状态码、响应头等日志信息
FULL:记录完整的请求、响应数据等日志信息
*/
@Bean
public Logger.Level level(){
return Logger.Level.FULL;
}
}
启用该 Bean
package com.feign;
import com.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
*
* feign声明式接口:用于发起远程调用
*
* 1. 定义接口
* 2. 接口上添加注解 @FeignClient,并设置 value 属性为服务提供者的应用名称
* 3. 编写调用接口,接口的声明规则和提供方接口保持一致(返回值和方法名可自定义)
* 4. 注入该接口对象,调用接口方法完成远程调用(自动拼接value与接口URI)
*/
@FeignClient(value="eureka-provider", configuration=FeignLogConfig.class) // 加入日志配置
public interface GoodsFeignClient {
@GetMapping("/goods/findOne/{id}")
public Goods findGoodsById(@PathVariable("id") int id);
}