Spring Cloud系列之Feign
Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之链路追踪
简介
feign是netfix开发的一个轻量级的restful的http服务客户端,用来发起请求、远程调用。是以java接口注解的方式调用http请求,而不用像java中通过封装http请求报文的方式直接调用。消费者拿到服务提供者的接口,然后像调用本地方法一样去调用远程的接口,本质上就是feign帮我们去做了封装并且发起请求。更符合面向接口化的编程逻辑。
-
可以帮助我们更加便捷优雅的调用http的API,不需要我们去拼接url通过restTmplate方式去调用远程接口
-
并且feign支持了springMVC注解
Feign入门
Feign服务提供者搭建
- 添加依赖
<dependencies>
<!-- eureka client依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- configClient依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- feign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 健康监测依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--链路追踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
</dependencies>
- FeignClient的创建
/**
* @Description:
* @author: dy
* @Date: 2021/11/26
*/
//@FeignClient表明当前类是一个feign客户端,value指定该客户端要请求的服务名称(登记到注册中心的服务提供者名称)
@FeignClient(value = "user-service",path = UserClient.MAPPING)
public interface UserClient {
String MAPPING = "/user-service";
@RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
public String getUserId();
}
/**
* @Description:
* @author: dy
*/
@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
public class UserResource implements UserClient {
@Autowired
private AppInfo appinfo;
@Override
public String getUserId() {
log.info("==============请求来了===============");
return "======111111222>>"+appinfo.getAppId();
}
}
- 启动类
/**
* @Description:
* @author: dy
*/
@EnableDiscoveryClient //开启Eureka客户端发现功能
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
Feign服务消费者搭建
- 引入依赖
<dependencies>
<!--引入user-service依赖-->
<dependency>
<groupId>com.dy</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--config-client依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</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-web</artifactId>
</dependency>
<!--链路追踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
</dependencies>
- 启动类 (开启feign客户端功能)
/**
* @Description:
* @author: dy
*/
//开启feign客户端功能 basePackages指定要扫描的feignClient类所在包路径
@EnableFeignClients(basePackages = {"com.dy.user.client"})
//开启Eureka客户端发现功能
@EnableDiscoveryClient
@SpringBootApplication
public class UserApiApplication {
public static void main(String[] args) {
SpringApplication.run(UserApiApplication.class, args);
}
}
- 使用
/**
* @Description:
* @author: dy
* @Date: 2021/11/29
*/
@Slf4j
@RestController
public class UserController implements UserApi {
@Autowired
private UserClient userClient;
@Override
public String getUserInfo() {
log.info("==========滴滴========");
return userClient.getUserId();
}
}
这样完成了feign的基本使用,但是我们思考一个问题?如果我们同时启动了几个service服务,那我们的api会调用哪个service呢?
feign对负载均衡的支持
feign自身已经集成了对ribbon依赖和自动配置,因此不需要我们引入额外对ribbon的依赖,可用通过在配置文件里面添加响应的配置进行全局的配置或者对某个服务单独的负载均衡配置。
feign默认的请求处理超时时长是1s,有时候肯定我们的业务处理逻辑是超过1s的,那么这些就需要我们根据自己的业务进行相应的配置,以满足我们对每个服务的调用需求
对单个服务的ribbon配置:
user-service:
ribbon:
#请求连接超时时间
ConnectTimeout: 3000
#请求处理超时时间
ReadTimeout: 15000
#对所有操作都进行重试
OkToRetryOnAllOperations: true
#对当前选中的实例重试次数,不包含第一次调用
MaxAutoRetries: 0
#切换实例的重试次数
MaxAutoRetriesNextServer: 0
#负载均衡策略配置
NFLoadBalancerRuleClassName: com.netfix.loadbalancer.RoundRobinRule
负载均衡逻辑如下:
-
根据上面得配置,当访问超时时,系统会再尝试一次访问当前实例(次数由MaxAutoRetries配置)
-
如果不行,就换一个实例进行访问,如果还不行,再换一个实例访问(更换次数由MaxAutoRetriesNextServer这个决定)
-
如果还不行,就返回失败结果
Ribbon默认的负载均衡策略是RoundRobinRule也就是轮询,当然在实际开发中我们可以根据我们服务的响应配置进行响应的负载均衡策略的自定义
对全局的ribbon配置(就把我们服务的名字去掉就可以了):
ribbon:
#请求连接超时时间
ConnectTimeout: 3000
#请求处理超时时间
ReadTimeout: 15000
#对所有操作都进行重试
OkToRetryOnAllOperations: true
#对当前选中的实例重试次数,不包含第一次调用
MaxAutoRetries: 0
#切换实例的重试次数
MaxAutoRetriesNextServer: 0
#负载均衡策略配置
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
Feign的日志级别配置
Feign是http请求的客户端,类似于浏览器,在请求和接受响应的时候,可以打印出比较详细的一些信息,比如:响应头、状态码等等
如果我们想看到Feign请求时的日志,我们可以进行一些配置,默认情况下Feign的日志是没有开启的。
- 在api module配置如下
/**
* @Description:
* @author: dy
*/
@Configuration
public class FeignConfig {
/**
*
* @return
*/
@Bean
Logger.Level feignLevel(){
return Logger.Level.FULL;
}
}
LEVEL说明:
-
NONE 不显示任何日志
-
BASIC 仅记录请求方法、URL、响应状态码、执行时间 ,适用于生产环境
-
HEADERS 在BASIC的基础上记录请求响应的header
-
FULL 记录请求响应的header、body、元数据 适用于开发及测试环境
注意配置log日志级别:
logging:
level:
com.dy.user: debug
运行结果如下:
Feign日志结果输出.pngFeign对熔断器的支持
- 在feign客户端配置文件添加配置开启对熔断的支持
#开启对hystrix的支持
feign:
hystrix:
enabled: true
上面我们设置了feign的超时时长设置实际上是对Ribbon的超时时长设置,但是如果开启了对hystrix的支持,hystrix还有超时时长设置,如下
hystrix:
command:
default:
execution:
isolation:
thread:
#hystrix超时时长设置
timeoutInMilliseconds: 5000
开启对hystrix支持后,Feginclient中的方法就会被进行一个管理了,一旦出现问题就会进行默认处理也就是fallback类的方法中的处理
注意:针对超时这块,这里有两个超时时间:一个是ribbon的超时时间,一个是hystrix的超时时间,熔断的时间就是根据两个时间中最小的超时时间来进行的,及最短超时时间
- clent类
/**
* @Description:
* @author: dy
*/
//@FeignClient表明当前类是一个feign客户端,value指定该客户端要请求的服务名称(登记到注册中心的服务提供者名称) fallback指定回退类
@FeignClient(value = "user-service",path = UserClient.MAPPING ,fallback = UserFallback.class)
public interface UserClient {
String MAPPING = "/user-service";
@RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
public String getUserId();
}
- 新建fallback方法
/**
* @Description: 降级回退逻辑定义一个类,实现Feign接口,实现其中的接口方法,返回默认值
* @author: dy
*/
@Component
public class UserFallback implements UserClient {
@Override
public String getUserId() {
return "-1";
}
}
Feign对请求响应压缩的支持
feign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗,这里我们就不进行过多介绍了。