对阿里巴巴微服务解决方案的一些理解

本文深入探讨了SpringCloud中的Sentinel组件,包括服务注册与发现、服务调用、网关、服务降级限流与熔断等核心功能。Sentinel提供了多种流控模式,如直接、关联、链路限流,以及快速失败、预热、排队等待等策略。此外,还详细介绍了Sentinel的熔断降级机制,包括慢调用比例、异常比例和异常数三种模式。最后,提到了分布式事务解决方案Seata的角色和工作流程。
摘要由CSDN通过智能技术生成

SpringCloud各种技术的对比

目前最新的一套

nacos(服务注册与发现+配置中心+服务总线)

openFeign(服务调用)+loadBalance(负载均衡)

gatewat(网关)

sentinel(服务降级限流与熔断)

seata(分布式事务)
在这里插入图片描述

网关的概念图

在这里插入图片描述

sentinel概念解析

阈值类型

QPS

QPS:每秒的请求数量

线程数

线程数:进入当前方法的线程数也就是请求数 servlet一个请求对于一个线程

流控模式

直接 关联 链路

直接

达到阈值,sentinel给出默认异常提示(blocking… 一句话)


关联

当关联的资源达到阈值时,就限流当前资源

通俗解释来说,比如那我们的程序,现在有testA接口和testB接口,当testA关联的资源testB达到阈值后,就限流testA。例如在一个电商系统中,当支付系统达到阈值,就限流下单系统,防止更多的订单产生的支付打垮了支付系统。

java代码:

package com.example.sentinel.service;
 
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class FlowLimitController {
    @GetMapping("/testA")
    public String testA(){
        return "-----testA";
    }
 
    @GetMapping("/testB")
    public String testB(){
        //返回js再次请求,保证QPS超过1,用于演示效果
        return "-----testB<script>setInterval(function(){window.location.reload();},500)</script>";
    }
}
 

js代码:

    setInterval(function(){
      window.location.reload();
    },500);

控制台操作:

在这里插入图片描述
效果图:

在这里插入图片描述


链路

假如某一个服务方法有多个调用来源, 如果我们只想限制来自于某一个来源的的调用路径, 就可以通过链路来限流

理解图:

代码:

@Service
public class TestService {
    @SentinelResource("myService")
    public String myService() {
        return "test service";
    }
}

@RestController
public class FlowLimitController {
    @Autowired
    private TestService testService;
 
    @GetMapping("/testA")
    public String testA() {
        return "-----testA - " + testService.myService();
    }
 
    @GetMapping("/testB")
    public String testB() {
        return "-----testB - " + testService.myService();
    }
}

控制台操作:

此时如果我们访问/testA会发现实际上是不会流控的,这是因为Sentinel 的 CommonFilter 的 web-context-unify 参数默认为true,表示要将调用链路收敛,会导致链路流控效果无效。 我们需要将这个参数设置成true才能取消链路收敛才会生效。

application.properties

spring.cloud.sentinel.web-context-unify=false

server.port=8401
spring.application.name=sentinel-service
spring.cloud.nacos.discovery.server-addr=192.168.43.11:8848
# 配置Sentinel dashboard地址
spring.cloud.sentinel.transport.dashboard=192.168.43.11:31808
# 默认8719端口,被占用会自动从8719+1,直到找到未被占用的端口
spring.cloud.sentinel.transport.port=8719
# 默认为true,表示将调用链路收敛,会导致链路流控效果无效,需要改成false
spring.cloud.sentinel.web-context-unify=false
# 暴露所有端点,给dashboard用
management.endpoint.web.exposure.include=*

效果:

流控效果

快速失败

**快速失败:**直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

warm up

**warm up(预热):**即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。

在5秒内最大阈值是3(10/codeFactor),超过5秒,最大阈值为10

控制台:

结果:

在5秒内狂点 http://localhost:8401/testA,发现超过3次就报错

超过5秒狂点 http://localhost:8401/testA,发现超过3次就不报错,超过10次才报错

排队等待

**排队等待:**匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

排队等待示意图:

排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为 QPS ,否则无效。

控制台:

排队等待总结:阈值类型必须为QPS,当QPS达到阈值时,不是立刻拒绝超过阈值的请求,而是让他们进入一个等待队列,等待队列根据一个公式 1000ms/阈值 的结果就是队列匀速放行请求到处理的服务器上,如果

eg:单机阈值设为5,1秒内通过5个,每200ms通过一次。
该限流好比一个漏斗,每隔200ms向漏斗中丢一个令牌,当请求拿到令牌就通过该漏斗,没有拿到令牌就在漏斗中等候令牌(队列的形式),直到请求的等待时间超过100ms(超时时间),该请求原地消失。
如果有高并发的请求进入:按照如上的配置只有第一个请求通过,其余请求全部超时消失

sentinel熔断降级

(1)慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
(2)异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
(3)异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

慢调用比例模式

满足两个条件会触发熔断:

1》单位统计时长请求数大于设置的最小值。下面是每秒钟5个。

2》慢请求达到设置的比例

/**
 * 通过此方法模拟慢调用,或不稳定资源(经常出异常)
 * AtomicXxx 底层基于CAS算法(乐观锁方式)保证了线程安全和性能
 */
private AtomicInteger atomicInteger = new AtomicInteger(1); //初始值1

@GetMapping("/sentinel05")
public String deSentinel05() throws InterruptedException {
    int count = atomicInteger.getAndIncrement();//先取值,再递增
    if (count %2 == 0) {
        Thread.sleep(200);  //模拟耗时
    }
    return "test Sentinel 05";
}

除了流量控制外,对调用链路中不稳定资源进行熔断降级可以保障高可用。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。

这里表示熔断策略选择"慢调用比例",表示请求数超过3时,假如平均响应时间超过200毫秒的有30%,则对请求进行熔断,熔断时长为10秒钟,10秒以后恢复正常。


异常比例

1》每秒钟请求超过五个

2》异常比例超过50%触发熔断

    @GetMapping("/testE")
    public JSONResultUtil<String> testE() {
        int i = 1 / 0;
        return JSONResultUtil.successWithData("testE");
    }


异常数模式

异常数模式:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断

时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错

误)则结束熔断,否则会再次被熔断。

注:统计时间默认为1s 不同版本的sentinel能给你设置的数据不一样


分布式事务seata

概念

分布式事务处理过程的 ID+三组件模型, ID即Transaction ID XID,全局唯一的事务ID。

三组件:

1.TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

2.TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。 @GlobalTransactional

3.RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交

或回滚。

Seata处理流程

在这里插入图片描述

如图所示一个TC管理全局,一个XID带着TC,TM,RM。

1.TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID。

2.XID在微服务调用链路的上下文中传播。

3.RM向TC注册分支事务,将其纳入XID对应的全局事务的管辖。

4.TM向TC发起针对XID的全局提交或回滚决议。

5.TC调度XID下管辖的全部分支事务完成提交或者回滚请求。

以下达订单为例,在Service层的saveOrder方法中需要调用订单服务的保存订单操作,并调用商品服务

中更新库存中的方法

如下图:

在这里插入图片描述

配置略

配置是否生效

启动日志中出现 Auto proxy of [dataSource] 、Global Transaction Clients are initialized. 表示已

在项目中集成 了seata

使用分布式事务

在service层需要使用分布式事务的方法上用 @GlobalTransactional注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值