系列文章目录
1、父工程创建
2、支付模块构建和热部署
3、消费者订单模块
4、服务注册中心-Eureka
5、zookeeper没学习
6、服务注册中心-Consul
7、Eureka、Consul异同
8、服务调用-Ribbon
9、服务调用-OpenFeign
10、服务降级-Hystrix
11、服务降级-Hystrix(二)
12、服务熔断-Hystrix
13、服务网关-Gateway
14-17 在git上做配置中心,没有学习
17、请求链路跟踪-Sleuth
18、Spring Cloud Alibaba-Nacos注册中心与配置中心
19、Spring Cloud Alibaba-Nacos集群和持久化配置
20、Sentinel流控
21、Sentinel熔断降级、热点key限流
22、SentinelResource配置
23、Sentinel 服务熔断与持久化
1. 概述
在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。
所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量
2. OpenFeign的集成
接口 + 注解
2.1 新建模块
新建module cloud-consume-fegin-order80
2.2 POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud2021</artifactId>
<groupId>com.chzu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-fegin-order80</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- commons -->
<dependency>
<groupId>com.chzu</groupId>
<artifactId>cloud-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web-->
<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>
</project>
2.3 YML
server:
port: 80
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
2.4 主启动类
@SpringBootApplication
@EnableFeignClients
public class FeignOrder80 {
public static void main(String[] args) {
SpringApplication.run(FeignOrder80.class,args);
}
}
2.5 业务类
业务逻辑接口 + @FeignClient配置调用provider服务
- 新建PaymentFeignService接口并新增注解@FeignClient
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")//告诉应该去找哪一个微服务
public interface PaymentFeignService {
@GetMapping("/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
- Controller
@RestController
@RequestMapping("consumer")
@Slf4j
public class OrderController {
@Autowired
private PaymentFeignService feignService;
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
return feignService.getPaymentById(id);
}
}
2.6 测试
先启动Eureke集群,在启动其他微服务
访问http://localhost/consumer/payment/get/20
feign自带负载均衡
3. OpenFeign的超时控制
3.1 超时情况演示
- 在payment8001、payment8002的controller中添加一个方法
@Autowired
private PaymentService service;
@Value("${server.port}")
private String serverPort;
.....
@GetMapping("/feign/timout")
public String paymentFeignTimout(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return serverPort;
}
- 在FeignOrder80的PaymentFeignService中添加
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")//告诉应该去找哪一个微服务
public interface PaymentFeignService {
@GetMapping("/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
@GetMapping("/payment/feign/timout")//添加的方法
String paymentFeignTimout();
}
- 在FeignOrder80的OrderController中添加
@RestController
@RequestMapping("consumer")
@Slf4j
public class OrderController {
@Resource
private PaymentFeignService feignService;
@GetMapping("/payment/feign/timout")
public String paymentFeignTimout(){
return feignService.paymentFeignTimout();
}
}
- 测试
访问http://localhost/consumer/payment/feign/timeout
报出错误"message": “Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/feign/timout”
报错原因:openfeign默认只等待一秒,超时会报错
3.2 超时控制
在yml设置feign的超时控制
server:
port: 80
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
feign:
client:
config:
default:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
connectTimeout: 7000
#指的是建立连接后从服务器读取到可用资源所用的时间
readTimeout: 7000
4. OpenFeign日志打印
4.1 配置OpenFeign日志
Feign提供了日志打印功能,我们可以通过配置来调整日恙级别,从而了解Feign 中 Http请求的细节。
Feign对接口的调用情况进行监控和输出
-
日志级别
- NONE:默认的,不显示任何日志;
- BASIC:仅记录请求方法、URL、响应状态码及执行时间;
- HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
- FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
-
日志配置FeignConfig
package com.chzu.springcloud.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author lwd
* @description feign配置类
* @create 2021/07/16
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
- YML文件里需要开启日志的Feign客户端
logging:
level:
#feign日志以什么级别监控哪一个接口
#现在是以debug的形式打印这个接口的FULL级别的全日志
com.chzu.springcloud.service.PaymentFeignService: debug
- 测试
访问http://localhost/consumer/payment/feign/timout,控制台显示信息更加详细