SpringCloud系列教程:微服务的未来(十九)请求限流、线程隔离、Fallback、服务熔断
前言
前言
在现代微服务架构中,系统的高可用性和稳定性至关重要。为了解决系统在高并发请求或服务不可用时出现的性能瓶颈或故障,常常需要使用一些技术手段来保证服务的平稳运行。请求限流、线程隔离、Fallback 和服务熔断是微服务中常用的四种策略,能够有效防止系统崩溃并提高用户体验。
- 请求限流:通过限制请求的数量,避免系统因过载而崩溃。
- 线程隔离:将请求处理和底层服务调用分开,防止一个服务的问题影响整个系统。
- Fallback:在服务不可用时,提供预设的降级策略,确保系统依然能够提供基本的服务。
- 服务熔断:在服务无法恢复时,主动断开连接,防止系统资源浪费和进一步恶化。
本文将深入探讨这些策略的原理和实现方式,以及如何在微服务架构中灵活应用这些技术来增强系统的健壮性和容错能力。
请求限流
在簇点链路后面点击流控按钮,即可对其做限流配置:
点击按钮后
QPS是每秒查询次数
这样查询购物车列表的流量限制设置为每秒5个,最大QPS为5.
通过Jmeter来进行测试
线程数代表用户数量;Ramp-Up时间代表用户访问时间,10秒,表示100个用户10秒内完成,即每秒就是10次;循环次数代表每个用户访问次数,1就是请求1次。
右击启动发起测试。
结果如下:
线程隔离
当商品服务出现阻塞或故障时,调用商品服务的购物车服务可能因此而被拖慢,甚至资源耗尽。所以必须限制购物车服务中查询商品这个业务的可用线程数,实现线程隔离。
在簇点链路的界面点击流控按钮
设置并发线程数
模拟业务延迟代码
//模拟业务延迟
ThreadUtil.sleep(500);
cart-service服务的application.yml文件,开启Feign的sentinel功能:
feign:
sentinel:
enabled: true # 开启feign对sentinel的支持
配置一下cart-service模块的application.yml文件,修改tomcat连接:
server:
port: 8082
tomcat:
threads:
max: 50 # 允许的最大线程数
accept-count: 50 # 最大排队等待数量
max-connections: 100 # 允许的最大连接
默认情况下SpringBoot项目的tomcat最大线程数是200,允许的最大连接是8492
重启cart-service服务,就发现查询商品的FeignClient自动变成一个簇点资源
Jemeter测试
启动测试后,查询购物车会失败
但是在此期间修改购物车是不受影响的
Fallback
1.将FeignClient作为Sentinel的簇点资源:
feign:
sentinel:
enabled: true # 开启feign对sentinel的支持
2.FeignClient的Fallback有两种配置方式
- 方式一:FallbackClass,无法对远程调用的异常做处理
- 方式二:FallbackFactory,可以对远程调用的异常做处理,通常都会选择这种
给FeignClient编写Fallback逻辑
假如有一个FeignClient如下:
@FeignClient(value ="userservice)
public interface Userclient {
@GetMapping("/user/{id}")
User findById(@Pa&variable("id")Long id);
}
为其编写Fallback逻辑
(1)自定义类,实现FallbackFactory,编写对某个FeignClient的fallback逻辑:
@slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable){
//创建UserClient接口实现类,实现其中的方法,编写失败降级的处理逻辑
returnnew UserClient(){
@Override
public User findById(Long id){
// 记录异常信息,可以返回空或抛出异常
log.error("查询用户失败",throwable);
return null;
}
}
(2)将刚刚定义的UserClientFallbackFactory注册为一个Bean:
@Bean
public UserClientFallbackFactory userClientFallback(){
return new UserClientFallbackFactory();
}
(3)在UserClient接口中使用UserClientFallbackFactory:
@FeignClient(value="userservice",fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient{
@GetMapping("/user/{id}")
User findById(@PathVariable("id")Long id);
}
以cart-service服务中查询购物车调用ItemClient为例,在hm-api服务中创建对应的ItemClientFallbackFactory类
package com.hmall.api.client.fallback;
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.Collection;
import java.util.List;
@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {
@Override
public ItemClient create(Throwable cause) {
return new ItemClient() {
@Override
public List<ItemDTO> queryItemsByIds(Collection<Long> ids) {
log.error("查询商品失败!",cause);
return CollUtils.emptyList();
}
@Override
public void deductStock(List<OrderDetailDTO> items) {
log.error("扣减商品库存失败!",cause);
throw new RuntimeException(cause);
}
};
}
}
注册为bean对象
@Bean
public ItemClientFallbackFactory itemClientFallbackFactory() {
return new ItemClientFallbackFactory();
}
在ItemClient接口中使用ItemClientFallbackFactory
服务熔断
熔断是解决雪崩问题的重要手段。思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。
点击熔断按钮后填写规则
- RT超过200毫秒的请求调用就是慢调用
- 统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断
- 熔断持续时长20s
启动Jemeter测试后发生熔断,没有查询商品的最新信息
总结
通过引入请求限流、线程隔离、Fallback 和服务熔断等策略,微服务架构可以有效应对高并发请求、服务故障等问题,保障系统的稳定运行。这些技术不仅能够防止系统由于单一服务故障而造成的级联效应,还能够提高用户体验和系统的响应速度。实现这些策略并不是一蹴而就的,它们需要与业务需求紧密结合,通过合理配置和监控,确保系统在高负载情况下仍然能够平稳运行。
随着微服务架构的不断发展,这些策略将变得更加重要,帮助开发者在复杂的分布式环境中维持系统的高可用性和稳定性。