10. SpringCloudAlibaba 实践笔记:服务容错基本知识

并发对系统的影响

使用压测的方式了解并发对系统的影响,测试步骤:

  1. 编写一个并发测试的接口。
  2. 限制 tomcat 的最大并发数。
  3. 使用 JMeter /order/submit_order 接口进行压测。
  4. 使用浏览器访问并发测试的接口,观察接口的性能。

编写并发测试接口

在 shop-order 的 OrderController 中新增一个临时方法 concurrentRequest() 用于做压测。

@GetMapping(value = "/concurrent_request")
public String concurrentRequest(){
    log.info("测试业务在高并发场景下是否存在问题");
    return "binghe";
}
  • 新增接口是为了测试在提交订单接口并发请求过高对订单微服务其他接口产生的影响。

限制 tomcat 的最大并发数

在订单微服务 shop-order 的 resources 目录下的 application.yml 文件中添加限制 tomcat 处理请求的最大并发数。

server:
  port: 8080
  tomcat:
    max-threads: 20
  • 限制 Tomcat 一次最多只能处理 20 个请求。

压测订单接口

打开 JMeter 的主界面

image

在 JMeter 中右键测试计划添加线程组

image

在 JMeter 中的线程组中配置并发线程数

image
将线程数配置成50,Ramp-Up时间配置成0,循环次数为100。表示JMeter每次会在同一时刻向系统发送50个请求,发送100次为止。

在 JMeter 中右键线程组添加 HTTP 请求

image

在 JMeter 中配置 HTTP 请求

image
具体配置如下所示。

  • 协议:http
  • 服务器名称或IP:localhost
  • 端口号:8080
  • 方法:POST
  • 路径:/order/submit_order
  • Body 值:略
  • 内容编码:UTF-8

添加 http header

image

  • 添加 Content-Type = application/json
    image

开始压测

点击 JMeter 上的绿色小三角开始压测
image
同时在浏览器或其他工具中访问 http://localhost:8080/order/concurrent_request ,会发现接口会卡顿,甚至根本访问不到。

服务雪崩

由于网络或者服务自身的问题,一般服务是很难做到100%高可用的。如果一个服务出现问题,就可能会导致其他的服务级联出现问题,这种故障性问题会在整个系统中不断扩散,进而导致服务不可用,甚至宕机,最终会对整个系统造成灾难性后果。

为了最大程度的预防服务雪崩,组成整体系统的各个微服务需要支持服务容错的功能。

服务容错方案

服务容错在一定程度上就是尽最大努力来兼容错误情况的发生,因为在分布式和微服务环境中,不可避免的会出现一些异常情况,我们在设计分布式和微服务系统时,就要考虑到这些异常情况的发生,使得系统具备服务容错能力。

常见的服务错误方案包含:服务限流、服务隔离、服务超时、服务熔断和服务降级等。

服务限流

服务限流就是限制进入系统的流量,以防止进入系统的流量过大而压垮系统。其主要的作用就是保护服务节点或者集群后面的数据节点,防止瞬时流量过大使服务和数据崩溃(如前端缓存大量失效),造成不可用;还可用于平滑请求。
限流算法有两种,一种就是简单的请求总量计数,一种就是时间窗口限流(一般为1s),如令牌桶算法和漏牌桶算法就是时间窗口的限流算法。

服务隔离

服务隔离有点类似于系统的垂直拆分,就按照一定的规则将系统划分成多个服务模块,并且每个服务模块之间是互相独立的,不会存在强依赖的关系。如果某个拆分后的服务发生故障后,能够将故障产生的影响限制在某个具体的服务内,不会向其他服务扩散,自然也就不会对整体服务产生致命的影响。
互联网行业常用的服务隔离方式有:线程池隔离信号量隔离

服务超时

整个系统采用分布式和微服务架构后,系统被拆分成一个个小服务,就会存在服务与服务之间互相调用的现象,从而形成一个个调用链。形成调用链关系的两个服务中,主动调用其他服务接口的服务处于调用链的上游,提供接口供其他服务调用的服务处于调用链的下游。

服务超时就是在上游服务调用下游服务时,设置一个最大响应时间,如果超过这个最大响应时间下游服务还未返回结果,则断开上游服务与下游服务之间的请求连接,释放资源

服务熔断

在分布式与微服务系统中,如果下游服务因为访问压力过大导致响应很慢或者一直调用失败时,上游服务为了保证系统的整体可用性,会暂时断开与下游服务的调用连接。这种方式就是熔断。
服务熔断一般情况下会有三种状态:关闭、开启和半熔断。

  • 关闭状态:服务一切正常,没有故障时,上游服务调用下游服务时,不会有任何限制。
  • 开启状态:上游服务不再调用下游服务的接口,会直接返回上游服务中预定的方法。
  • 半熔断状态:处于开启状态时,上游服务会根据一定的规则,尝试恢复对下游服务的调用。此时,上游服务会以有限的流量来调用下游服务,同时,会监控调用的成功率。如果成功率达到预期,则进入关闭状态。如果未达到预期,会重新进入开启状态。

服务降级

服务降级,就是一种服务托底方案,如果服务无法完成正常的调用流程,就使用默认的托底方案来返回数据。例如,在商品详情页一般都会展示商品的介绍信息,一旦商品详情页系统出现故障无法调用时,会直接获取缓存中的商品介绍信息返回给前端页面。

服务容错组件

实现服务容错功能的组件不仅仅有Sentinel,比如:Hystrix 和 Resilience4J 也能够实现服务容错的目的。

Hystrix

Hystrix 是 Netflix 开源的一个延迟和容错库,主要用于通过隔离服务之间的访问点、停止级联故障并提供回退选项来提高分布式系统的弹性。

Hystrix 的主要功能包括:

  • 服务熔断:当某个服务的错误率达到一定阈值时,Hystrix 会自动开启熔断,停止对该服务的调用,一段时间后再进行试探性恢复调用。这样可以防止故障在系统中传播,避免整个系统崩溃。
  • 服务降级:当服务不可用时,Hystrix 可以提供降级处理,返回一个预设的默认值或者执行一个备用逻辑,以保证系统的基本可用性。
  • 服务隔离:Hystrix 使用线程池或信号量来隔离不同服务的调用,避免某个服务的故障影响到其他服务的正常运行。

Resilience4J

Resilience4j 是一个轻量级的容错库,灵感来自于 Hystrix,但在设计上更加简洁和灵活。

Resilience4J 的主要功能包括:

  • 服务熔断:与 Hystrix 类似,Resilience4j 也提供了熔断功能。当某个服务的错误率达到一定阈值时,熔断器会打开,阻止对该服务的调用,一段时间后再进行试探性恢复调用。
  • 服务降级:可以定义当服务不可用时的降级逻辑,返回一个预设的默认值或者执行一个备用逻辑。
  • 服务限流:通过 RateLimiter 模块可以限制对某个服务的调用频率,防止系统被过度调用而导致性能下降。
  • 重试机制:当调用失败时,可以配置重试策略,自动进行重试。
posted @ 2024-11-06 22:58  Jacob-Chen  阅读(61)  评论(0)    收藏  举报