微服务保护学习笔记(四)FeignClient整合Sentinel、线程隔离(舱壁模式)、熔断降级

前言

微服务保护学习笔记(一)雪崩问题及解决方案、Sentinel介绍与安装
微服务保护学习笔记(二)簇点链路、流控操作、流控模式(关联、链路)
微服务保护学习笔记(三)流控效果(warm up、排队等待)、热点参数限流

3 隔离和降级

限流是一种预防措施,它可以尽量避免因高并发而引起的服务故障。但服务还会因为其它原因而故障,而要将这些故障控制在一定范围内避免雪崩,就要依靠线程隔离(舱壁模式)和熔断降级手段了。

  • 线程隔离:服务调用者在调用服务提供者时,给每个调用请求分配独立线程池,出现故障时,这个请求最多消耗这个线程池内的资源,避免把调用者的所有资源耗尽。

  • 熔断降级:在调用方这边加入断路器,统计对服务提供者的调用,如果调用的失败比例过高,则熔断该业务,不允许访问该服务提供者。

可以看到,不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护,需要在调用方发起远程调用时做线程隔离或者服务熔断。

SpringCloud微服务远程调用都是基于Feign来完成的,因此需要将Feign与Sentinel整合,在Feign里面实现线程隔离和服务熔断。

3.1 FeignClient整合Sentinel

3.1.1 搭建SpringCloud项目

创建一个SpringCloud项目,sd-user-servicesd-order-service微服务均注册到Eureka中:

sd-user-service微服务中有一个/user/query接口,调用该接口后会通过Feign调用sd-order-service微服务:

// com.hsgx.user.controller.UserController

@Autowired
private OrderClient orderClient;

@GetMapping("/query")
public String query(String id) {
    String order = orderClient.queryById(id);
    return "查询用户" + id + "成功," + order;
}
// com.hsgx.order.controller.OrderController

@GetMapping("/query")
public String query(String id) {
    return "查询订单" + id + "成功";
}

3.1.2 修改配置文件

修改sd-user-service微服务(调用方)的配置文件,开启Feign的Sentinel功能:

feign:
  sentinel:
    enabled: true

3.1.3 编写失败降级逻辑

业务失败后,不能直接报错,而应该返回一个友好提示或者默认结果,这就是失败降级逻辑。

  • 1)在sd-user-service微服务中定义类,实现FallbackFactory
// com.hsgx.user.config.OrderClientFallbackFactory

public class OrderClientFallbackFactory implements FallbackFactory<OrderClient> {
    @Override
    public OrderClient create(Throwable throwable) {
        return new OrderClient() {
            @Override
            public String queryById(String id) {
                return "调用order微服务失败";
            }
        };
    }
}
  • 2)在DefaultFeignConfiguration类中将OrderClientFallbackFactory注册为一个Bean
// com.hsgx.user.config.DefaultFeignConfiguration

@Bean
public OrderClientFallbackFactory orderClientFallbackFactory(){
    return new OrderClientFallbackFactory();
}
  • 3)在OrderClient接口中使用OrderClientFallbackFactory
// com.hsgx.user.feign.OrderClient

@FeignClient(value = "sd-order-service",
        configuration = DefaultFeignConfiguration.class,
        fallback = OrderClientFallbackFactory.class)
public interface OrderClient {
    @GetMapping("/order/query")
    String queryById(@RequestParam("id") String id);
}

重启sd-user-service微服务后,再次访问/user/query接口,然后查看Sentinel控制台,可以看到新的簇点链路:

3.2 线程隔离(舱壁模式)

3.2.1 线程隔离的实现方式

如上图所示,线程隔离有两种方式实现:

  • 线程池隔离:给每个调用业务分配一个线程池,利用线程池本身实现隔离效果。例如,给访问服务A的线程分配一个单独的线程池,如果访问服务A失败,则只在当前线程池中失败,而不会影响其他线程池。
  • 信号量隔离(即QPS):不创建线程池,而是计数器模式,记录调用业务使用的线程数量,达到信号量上限时,禁止新的请求。

3.2.2 线程池隔离

在给资源添加限流规则时,阈值类型可以选择“QPS”或者“线程数”。而选择“线程数”时,就是该资源能使用的线程数最大值,从而实现线程隔离。

下面对线程池隔离进行测试:

  • 1)配置隔离规则,使GET:http://sd-order-service/order/query资源的最大线程数为2

  • 2)使用jmeter进行测试,使线程数为10

  • 3)测试/user/query?id=1

测试结果发现,虽然结果都是通过,不过部分请求得到的响应是降级后的。测试结果符合预期。

3.3 熔断降级

3.3.1 熔断降级的实现方式

熔断降级思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该调用服务,即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。

断路器控制熔断和放行是通过状态机来完成的:

如上图所示,状态机包括三个状态:

  • closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则会切换到open状态。
  • open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。open状态5秒后会进入half-open状态。
  • half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。如果请求成功,则切换到closed状态;如果请求失败,则切换到open状态。

在Sentinel控制台新增降级规则时,有三种熔断策略可选:

3.3.2 慢调用比例

响应时长(RT)大于指定时长的调用请求则被认定为慢调用请求。该策略的原理如下:

在以上配置中,RT超过500ms的请求则是慢调用请求。统计最近10000ms内的调用请求,如果请求量超过10次,且慢调用比例超过0.5(即超过5次),则触发熔断,熔断时长为5秒。然后状态机进入half-open状态,放行一次请求做测试。

下面对慢调用策略进行测试:

  • 1)修改sd-order-service微服务的/order/query接口,通过休眠模拟一个延迟时间:
@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/query")
    public String query(String id) throws InterruptedException {
        if("1".equals(id)) {
            // 当id=1时,触发慢调用
            Thread.sleep(600);
        }
        return "查询订单" + id + "成功";
    }

}

此时调用/order/query?id=1接口的响应时间较长,超过500ms,将被认定为慢调用请求:

而调用/order/query?id=2接口的响应时间很短,不超过500ms,将不会被认定为慢调用请求:

  • 2)设置熔断规则

  • 3)使用jmeter进行测试,设置20秒内发送50个请求

  • 4)调用/user/query?id=1接口

  • 5)调用/user/query?id=2接口

3.3.3 异常比例、异常数

异常比例和异常数策略的原理是一样的,只是前者以比例来限定阈值,后置以具体的数值来限定阈值,例如:

在以上配置中,统计最近1000ms内的调用请求,如果请求量超过10次,且异常比例超过0.4(异常数超过4次),则触发熔断,熔断时长为5秒。

下面对异常比例策略进行测试:

  • 1)修改sd-order-service微服务的/order/query接口,手动抛出异常,模拟出现异常:
@GetMapping("/query")
public String query(String id) throws InterruptedException {
    if("1".equals(id)) {
        // 当id=1时,触发慢调用
        Thread.sleep(600);
    }
    if("2".equals(id)) {
        // 当id=2时,触发异常
        throw new RuntimeException("查询订单异常");
    }
    return "查询订单" + id + "成功";
}
  • 2)调用/user/query?id=3接口,此时是正常访问的

  • 3)设置上述熔断规则,并使用jmeter进行测试,设置1秒内发送20个请求调用/user/query?id=2接口,触发熔断

  • 4)在5s内再次调用/user/query?id=3接口,会发现已被阻止,即熔断已发生。5s后再次调用,发现服务恢复正常。

本节完,更多内容请查阅分类专栏:微服务学习笔记

感兴趣的读者还可以查阅我的另外几个专栏:

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰色孤星A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值