OpenFeign
Feign 是 SpringCloud 组件中的一个轻量级 RESTful 的 HTTP 服务客户端。Feign 内置了 Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign 的使用方式是:使用 Feign 的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。
OpenFeign 是 SpringCloud 在 Feign 的基础上支持了 SpringMVC 的注解,如 @RequesMapping。OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,在实现类中做负载均衡并调用其它服务。
服务调用
准备工作
创建一个 Module,一个空的 Maven 项目。并导入下面的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>ml.guest997</groupId> <artifactId>Commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
|
在 resources 文件夹下创建 application.yaml 配置文件,并加入下面的配置。
1 2 3 4 5 6 7 8 9 10 11 12
| server: port: 80
spring: application: name: order
eureka: client: register-with-eureka: true service-url: defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/
|
主启动类
1 2 3 4 5 6 7 8 9 10 11 12 13
| package ml.guest997;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication @EnableFeignClients public class Order2 { public static void main(String[] args) { SpringApplication.run(Order2.class, args); } }
|
Service 层
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package ml.guest997.service;
import ml.guest997.pojo.CommonResult; import ml.guest997.pojo.Payment; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping;
@Component @FeignClient("PAYMENT") public interface PaymentService { @GetMapping("/payment/add") CommonResult add(Payment payment); }
|
Controller 层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package ml.guest997.controller;
import lombok.extern.slf4j.Slf4j; import ml.guest997.pojo.CommonResult; import ml.guest997.pojo.Payment; import ml.guest997.service.PaymentService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController @Slf4j public class OrderController { @Resource private PaymentService paymentService;
@GetMapping("/consumer/payment/add") public CommonResult add(Payment payment) { return paymentService.add(payment); } }
|
测试
分别启动 Eureka-Server、Payment、Payment2 和 Order2 模块后,浏览器多次访问:127.0.0.1/consumer/payment/add?serial=Guest006,会发现端口是互相切换的,就说明 OpenFeign 内部已经实现了负载均衡。
超时控制
OpenFeign 调用远程服务时,一定时间内没有建立起请求或没有响应,就会报错。
添加支付 Controller
1 2 3 4 5 6 7 8 9
| @GetMapping("/payment/timeout") public String paymentTimeout() { try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return serverPort; }
|
添加订单接口
1 2
| @GetMapping("/payment/timeout") String paymentTimeout();
|
添加订单 Controller
1 2 3 4
| @GetMapping("/consumer/payment/timeout") public String paymentFeignTimeout() { return paymentService.paymentTimeout(); }
|
测试
分别启动 Eureka-Server、Payment、Payment2 和 Order2 模块后,浏览器访问:127.0.0.1/consumer/payment/timeout,过了一段时间后就会发现页面报错了。
添加配置
1 2 3 4 5 6
| feign: client: config: default: connectTimeout: 3000 readTimeout: 80000
|
日志增强
通过配置来调整日志级别,从而了解请求中的细节。
日志级别
- NONE:默认的,不显示任何日志。
- BASIC:仅记录请求方法、URL、响应状态码及执行时间。
- HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息。
- FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
配置类
1 2 3 4 5 6 7 8 9 10 11 12 13
| package ml.guest997.config;
import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
|
添加配置
1 2 3
| logging: level: ml.guest997.service.PaymentService: debug
|
测试
分别启动 Eureka-Server、Payment、Payment2 和 Order2 模块后,浏览器访问:127.0.0.1/consumer/payment/add?serial=Guest007,会发现控制台的输出内容如下图所示。
![]()