SpringCloud Alibaba Sentinel 创建流控规则

一、前言

        接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第十四篇,即介绍 SpringCloud Alibaba Sentinel 创建流控规则。

二、基本介绍

        我们在 sentinel 的管理界面上为我们的请求设置流量监控的规则,有两种方式,如下图:

        点击 + 号,配置流控规则,界面如下图,接下来详细介绍下可以配置的标签

2.1 资源名

        唯一名称,默认请求路径。即工程里面 controller 层方法上面的请求路径。

2.2 针对来源

        Sentinel 可以针对调用者进行限流,填写微服务名,默认 default (不区分来源)。

2.3 阈值类型

        QPS(每秒钟的请求数量):当调用该 api QPS 达到阀值的时候,进行限流。

        线程数:当调用该 api 的线程数达到阀值的时候,进行限流。

2.4 单机阈值

        一个具体的数字,为阀值类型所使用。

2.5 是否集群

        不需要集群。

2.6 流控模式

        1、直接:api 达到限流条件时,直接限流。

        2、关联:当关联的资源达到闻值时,就限流自己

        3、链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到闻值,就进行限流)[api 级别的针对来源]。

2.7 流控效果

        1、快速失败: 直接失败,抛异常

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

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

三、流控模式

3.1 直接

        接下来我们配置一个系统默认的流控规则,即 QPS -直接-快速失败,如下图,表示 1s 内查询一次是没有问题的,但是在 1s 内点击超过一次就直接快速失败,报默认错误。

        快速点击访问 http://localhost:8401/testB,如下图,可以看到,第一次请求是没有任何问题的,

        但是当我们狂点的时候,就会返回给我们限流的提醒了,如下图:

        

        修改我们刚刚创建的流控规则,将 QPS -直接-快速失败 模式修改为  并发线程数 -直接-快速失败 ,如下图:

        快速点击访问 http://localhost:8401/testB,如下图,可以看到,一直没有报错信息

        这是因为 QPS 和并发线程数是两种不同的流控效果,即 QPS 有流控效果,而并发线程数没有流控效果,从上面配置时的两张图片对比就可以看的出来。

        当有一堆请求发送过来时(高并发场景),QPS 流控就会将请求全部拦截在门外,根本接触不到里面的路径,而并发流控则是将请求放进来,但是只能有一个请求得到处理,其他的请求直接失败报错。

        上面一直调用成功的原因是后台处理请求在一瞬间就完成了,为了演示流控的效果,我们修改下 FlowLimitController 的代码,延长下 testB() 方法的处理时间,代码如下:

@RestController
public class FlowLimitController {@GetMapping("/testA")
public String testA(){return "------testA";}@GetMapping("/testB")
public String testB(){try {Thread.sleep(800);} catch (InterruptedException e) {throw new RuntimeException(e);}return "------testB";}
}

        打开两个浏览器窗口,分别调用 http://localhost:8401/testB,如下图,第一次调用没有任何问题,如下图:

        第二次调用就返回异常信息了(点击的速度得快,要不演示不出来),如下:

3.2 关联

        当关联的资源达到阈值时,就限流自己,当与 A 关联的资源 B 达到阀值后,就限流 A 自己,举个简单的例子就是支付模块快爆炸了,就限流下订单模块。

        在 sentinel 的管理界面配置一个关联的限流规则,如下,当关联资源 /testBqps 阀值超过 1 时,就限流 /testARest 访问地址,当关联资源到阈值后限制配置好的资源名。

        测试之前先把  FlowLimitController 的代码改回来,如下:

@RestController
public class FlowLimitController {@GetMapping("/testA")public String testA(){return "------testA";}@GetMapping("/testB")public String testB(){return "------testB";}
}

        为了演示模拟的效果,我们需要使用 postman 进行并发密集访问 /testB,打开 postman,创建一个新的 collection,如下图:

        接下来创建一个新的请求,记得保存这个请求,如下图:

        接下来配置运行的参数,如下图:

        配置一个线程组,包含 20 个线程,每隔 0.3s 访问一次 

        然后调用 http://localhost:8401/testA ,可以发现 testA 挂了,如下图:

3.3 链路

        假设一个 controller 里面的两个服务都会调用同一个 service 层里面的服务,这样就会形成两条链路,但是由于 service 层的资源是有限的,我们可以通过配置链路的流控模式来保证某一条链路一直可以正常使用,但另一条链路可能就会多担待一点。

        它和我们的关联模式有点像,也是保证一个接口可以正常使用,而牺牲了另外一个接口。接下来我们使用代码来演示下。

        首先需要创建一个 service 层,并编写一个方法,这个方法是给 controller 层的两个方法提供服务的,并在方法上添加 @SentinelResource 注解,这个注解用于标记需要被流量控制、熔断降级以及系统保护等功能覆盖的方法或类。这个注解允许开发者自定义资源名称,并且可以配置异常处理逻辑和 fallback 函数。代码如下:

package com.springcloud.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;@Service
public class FlowLimitService {@SentinelResource("todoService")public  void todoService(){System.out.println("....todoService....");}
}

        接下来需要在我们的配置文件里面添加一些配置,配置文件里面默认采用的是聚合的方式,我们这里改成 false,采用展开的模式,即我们有多少个链路都把它展示出来。

        接下来修改 controller 类的代码,让其调用 service 层的方法,如下:

@RestController
public class FlowLimitController {@ResourceFlowLimitService flowLimitService;@GetMapping("/testA")public String testA(){flowLimitService.todoService();return "------testA";}@GetMapping("/testB")public String testB(){flowLimitService.todoService();return "------testB";}
}

        接下来打开 sentinel 的管理界面,首先调用 testA testB 服务,如下图:

        如果我们没有在配置文件里面配置 web-context-unify: false 这个标签,或者配置完了这个标签出现下面的这种情况。

        原因可能是因为 spring-cloud-starter-alibaba-sentinel 版本太低,将其改成下面的版本即可。

<!-- 流量控制sentinel依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.5.RELEASE</version>
</dependency>

         接下来配置链路的流控,我们对 testA 的链路进行限流,如下图:

        此时疯狂调用 http://localhost:8401/testB,如下图,没有任何反应,可以正常返回

        疯狂调用 http://localhost:8401/testA,如果频率高一些就会报错,如下图: 

         证明我们的链路调用限流成功了。

四、流控效果

4.1 快速失败

        这种流控效果上面我们做了大量的例子,就是直接失败,抛出异常,如下图:

4.2 Warm Up 预热

        当流量突然增大的时候,我们常常会希望系统从空闲状态到繁忙状态的切换的时间长一些。即如果系统在此之前长期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最大值。Warm Up(冷启动,预热)模式就是为了实现这个目的的。

        这个场景主要用于启动需要额外开销的场景,例如建立数据库连接等。

        它有一个公式:初始阈值 = (配置的阈值)除以( codeFactor 默认值为 3),

        经过预热时长后才会达到配置的阈值。这样讲很抽象,我们配置一个来展示下,首先把 controller 代码恢复成原来的样子,如下图:

@RestController
public class FlowLimitController {@GetMapping("/testA")public String testA(){return "------testA";}@GetMapping("/testB")public String testB(){return "------testB";}
}

        配置预热的流控效果,如下图,​我希望每秒钟可以承受 10 QPS,但是我给你慢慢的预热起来,由于冷加载默认因子是 310/3 =3 ,那么一开始单机的阈值就是 3,但是给了你一个缓冲预热的时间 5s,让你 5s 内,慢慢的从 3 过度到 10

        此时疯狂调用 http://localhost:8401/testB,可以发现一开始有成功有失败,但到后来就都是成功的了。

         其使用场景是:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值

4.3 排队等待

        匀速排队方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。该方式的作用如下图所示:

        这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

        注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

        修改下 controller 类的代码,加一个日志打印的功能,如下:

@RestController
@Slf4j
public class FlowLimitController {@GetMapping("/testA")public String testA(){return "------testA";}@GetMapping("/testB")public String testB(){log.info(Thread.currentThread().getName()+"\t"+"testB");return "------testB";}
}

        配置排队等待的流控效果,如下图,设置单机阈值为 1,超时时间为 2s。​

         接下来使用 postman 进行多线程调用测试,和 5.2.2 小节用的方式一样,调用 collenction,如下图:

        查看控制台的日志信息,如下,可以看到,都是 1s 内调用一次,很舒服

五、降级规则

5.1 简介

        降级规则又称为熔断降级,除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

        现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。

        本文档针对 Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级,请使用最新版本以更好地利用熔断降级的能力。

        Sentinel Hystrix 的原则是一致的:当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。 

5.2 熔断策略

        熔点策略分为三种:慢调用比例、异常比例和异常数三种。

5.3 慢调用比例

        慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

        在 FlowLimitController 类中新增一个测试方法 testD,代码如下:

@RestController
@Slf4j
public class FlowLimitController {@GetMapping("/testA")public String testA() {return "------testA";}@GetMapping("/testB")public String testB() {log.info(Thread.currentThread().getName() + "\t" + "testB");return "------testB";}@GetMapping("/testD")public String testD() {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}log.info("testD 测试RT");return "------testD";}
}

        在 sentinel 中配置降级规则,如下图:

        设定允许的最大响应时间 RT = 900ms,统计最近 10000ms 内的请求,若请求超过 5 次,并且慢调用的比例超过 0.5,则触发熔断,熔断时长为 2s,然后进入 half-open 状态,放行一次请求做测试。

        接下来我们使用 postman 进行测试,使用 10 个线程调用我们的方法,如下图:

        等 postman 调用结束后,测试当前 testD 的状态,如下图,可以发现处于熔断状态了。

        等到 2s 之后,再次刷新浏览器,可以看到,又恢复正常了,如下图:

5.4 异常比例

        异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%

        修改 FlowLimitController 类中的测试方法 testD,代码如下:

    @GetMapping("/testD")public String testD() {log.info("testD 测试异常调用");int age = 10 / 0;return "------testD";}

        在 sentinel 中配置降级规则,如下图:

        统计最近 10000ms 内的请求,若请求超过 5 次,并且异常的比例超过 0.5,则触发熔断,熔断时长为 3s,然后进入 half-open 状态,放行一次请求做测试。 

        我们先在浏览器访问一下方法,如下,可以看到返回的是错误的界面。

        接下里我们使用 postman 进行测试,使用 10 个线程调用我们的方法,如下图:

        调用结束后再次在浏览器访问 testD,可以看到,返回的是限流的界面,如下图:

        等到 3s 之后,再次访问,可以看到,又出现了错误的界面,如下:

5.5 异常数

        异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

        在 FlowLimitController 类中的新增测试方法 testE,代码如下:

    @GetMapping("/testE")public String testE() {log.info("testE 测试异常数");int age = 10 / 0;return "------testE";}

        在 sentinel 中配置降级规则,如下图: 

        统计最近 10000ms 内的请求,若请求超过 5 次,并且异常数超过 5 个,则触发熔断,熔断时长为 3s,然后进入 half-open 状态,放行一次请求做测试。 

        在浏览器多次访问 testE,可以发现,前五次返回的页面如下:

        等到第六次,返回的就是流控的界面了,如下:

六、热点参数限流

6.1 简介

        何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

        1、商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制。

        2、用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

        热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

6.2 案例演示

        在 FlowLimitController 类中的新增两个方法,代码如下,@SentinelResource 注解我们在 上面提到过,用于标记需要被流量控制、熔断降级以及系统保护等功能覆盖的方法或类。

        它里面有个 blockHandler 属性,用于指定兜底的方法,兜底方法分为系统默认和客户自定义两种,在之前的案例中,限流出问题后,都是用 sentinel 系统默认的提示:Blocked by Sentinel (flow limiting)。这次我们指定兜底的方法为下面的 deal_testHotKey

    @GetMapping("/testHotKey")@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2) {return "------testHotKey";}public String deal_testHotKey (String p1, String p2, BlockException exception){// sentinel系统默认的提示:Blocked by Sentinel (flow limiting)return "------deal_testHotKey,o(╥﹏╥)o";}

        接下里我们在 sentinel 中配置热点规则,如下:

        限流模式只支持 QPS 模式,固定写死了。@SentinelResource 注解的方法参数索引,0 代表第一个参数,1 代表第二个参数,以此类推。单机阀值以及统计窗口时长表示在此窗口时间超过阀值就限流。

        上面配置的规则为:1sQPS 1,超过就限流,限流后调用 dealHandler testHotKey 支持方法。

        在浏览器访问:http://localhost:8401/testHotKey,怎么点击都不会出现限流的效果,因为并没有传输参数。

       在浏览器访问:http://localhost:8401/testHotKey?p1=a,如果 1s 点击一下就会出现下面的现象:

        如果点击频繁,就会出现限流的效果,如下:

       在浏览器访问:http://localhost:8401/testHotKey?p2=b,随便点,也不会出现限流的效果,因为我们没有对第二个参数进行配置,所以不用限流,如下:

6.3 特殊情况

        上述案例演示了第一个参数 p1,当 QPS 超过 1s 点击一次后马上被限流,但是我们期望当 p1 参数是某个特殊值时,它的限流值和平时不一样,比如说当 p1 的值等于 5 时,它的阈值可以达到 200,那么我们该如何配置呢?

        修改我们刚才配置的 sentinel 热点规则,打开参数例外项,需要注意的是:参数类型必须是基本类型或者 String,如下图:

       在浏览器访问:http://localhost:8401/testHotKey?p1=5,可以看到,无论点击多么频繁都不会出现限流的现象,如下图:

       在浏览器访问:http://localhost:8401/testHotKey?p1=4,可以看到,超过 1s 点击一次就会出现限流的现象,如下图,当 p1 不等于 5 的时候,阈值就是平常的 1

6.4 异常情况

        修改 FlowLimitController 类,手动添加一个异常试试,如下:

    @GetMapping("/testHotKey")@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2) {int age = 10/0;return "------testHotKey";}public String deal_testHotKey (String p1, String p2, BlockException exception){// sentinel系统默认的提示:Blocked by Sentinel (flow limiting)return "------deal_testHotKey,o(╥﹏╥)o";}

        在浏览器访问:http://localhost:8401/testHotKey,可以看到,直接就报错了,如下图:

        这是因为 @SentinelResource 处理的是 Sentinel 控制台配置的违规情况,有 blockHandler 方法配置的兜底处理。而 int age = 10/0,这个是 java 运行时报出的运行时异常 RunTimeException@SentinelResource 不管。

        总结起来就是 @SentinelResource 主管配置出错,运行出错该走异常走异常。

七、系统规则

7.1 简介

        系统规则又称为系统自适应限流,是从应用级别的入口流量进行控制,从单台机器的 loadCPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。前面我们所配置的限流都是方法级别的限流,而系统规则则是对整个应用进行限流的操作。

        系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量,比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

7.2 分类

        1、Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5

        2、CPU usage1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。

        3、平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。

        4、并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。

        5、入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

7.3 案例演示

        在 sentinel 控制台新增一个入口 QPS 的系统规则,如下图:

        在浏览器访问 http://localhost:8401/testB,当 1s 点击一下时,效果如下图,没有任何问题

        当频繁点击时就会出现限流的效果,如下图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/300571.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UltraScale 架构 SelectIO 资源之IODELAY与IOSERDES仿真与使用

平台&#xff1a;vivado2018.3 具体内容见ug571-ultrascale-selectio IDELAYE3 在调试超高速信号的时候&#xff0c;需要使用iodelayiserdes来调试校准输入信号。例如外部某ADC采样率为5GHZ&#xff0c;外部ADC使用2.5GHZ的时钟去采集输入信号。为了实现采集&#xff0c;adc芯…

90天玩转Python—05—基础知识篇:Python基础知识扫盲,使用方法与注意事项

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

如何搭建APP分发平台分发平台搭建教程

搭建一个APP分发平台可以帮助开发者更好地分发和管理他们的应用程序。下面是一个简要的教程&#xff0c;介绍如何搭建一个APP分发平台。 1.确定需求和功能&#xff1a;首先&#xff0c;确定你的APP分发平台的需求和功能。考虑以下几个方面&#xff1a; 用户注册和登录&#xff…

Stable Diffusion扩散模型推导公式的基础知识

文章目录 1、独立事件的条件概率2、贝叶斯公式、先验概率、后验概率、似然、证据3、马尔可夫链4、正态分布 / 高斯分布5、重参数化技巧6、期望7、KL散度 、高斯分布的KL散度8、极大似然估计9、ELBO :Evidence Lower Bound10、一元二次方程 1、独立事件的条件概率 A 和 B 是两个…

Vue项目打包成exe文件(electron)

1.将写好的vue项目打包 1.1运行vue ui命令 输出目标文件 如果打开index.html是空白的&#xff0c;而且控制台报错获取xxx资源失败的问题&#xff0c;你需要在vue.config.js 上加一个命令&#xff0c;如果没有你需要创建一个。 2.下载electron官方示例 git clone https://gith…

zdpdjango_argonadmin Django后台管理系统中的常见功能开发

效果预览 首先&#xff0c;看一下这个项目最开始的样子&#xff1a; 左侧优化 将左侧优化为下面的样子&#xff1a; 代码位置&#xff1a; 代码如下&#xff1a; {% load i18n static admin_argon %}<aside class"sidenav bg-white navbar navbar-vertical na…

Python---Numpy线性代数

1.数组和矩阵操作&#xff1a; 创建数组和矩阵&#xff1a;np.array, np.matrix 基本的数组操作&#xff1a;形状修改、大小调整、转置等 import numpy as np# 创建一个 2x3 的数组 A np.array([[1, 2, 3], [4, 5, 6]]) print("数组 A:\n", A)# 将数组 A 转换为矩阵…

趣学前端 | 综合一波CSS选择器的用法

背景 最近睡前习惯翻会书&#xff0c;重温了《HTML5与CSS 3权威指南》。这本书&#xff0c;分上下两册&#xff0c;之前读完了上册&#xff0c;下册基本没翻过。为了对得起花过的每一分钱&#xff0c;决定拾起来近期读一读。 CSS 选择器 在CSS3中&#xff0c;提倡使用选择器…

git bash上传文件至github仓库

Linux运维工具-ywtool 目录 一.访问github二.新建仓库1.点击自己头像2.选择"your repositories"3.点击"New"4.创建新仓库 三.通过git bash软件上传文件1.提示2.打开git bash软件3.切换到本地仓库目录4.配置github的用户名和邮箱信息5.生成SSH Key6.github添…

如何理解图像处理领域的病态问题(ill-posed problem)

ill-posed problem&#xff0c;我们可以理解为病态问题或者不适定问题。在本文中&#xff0c;统一成为不适定问题。 在讨论不适定问题&#xff08;ill-posed problem&#xff09;之前&#xff0c;我们先来看一下什么叫适定性问题&#xff08;well-posed problem&#xff09;。…

MVCC(解决MySql中的并发事务的隔离性)

MVCC 如何保证事务的隔离性&#xff1f; 1.排他锁&#xff1a;如一个事务获取了一个数据行的排他锁&#xff0c;其他事务就不能再获取改行的其他锁。 2.MVCC&#xff1a;多版本并发控制。 MVCC&#xff1a; 1.隐藏字段 1.DB_TRX_ID&#xff1a;最近修改事务的id。默认值从0开…

前端:SVG绘制流程图

效果 代码 html代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>SVG流程图示例</title><style>/* CSS 样式 */</style><script src"js/index.js"></script…

1、java语法入门(找工作版)

文章目录 一、Java简介二、Java常量与变量1、标识符2、关键字3、变量4、类的命名规则5、数据类型6、基本数据类型字面值7、变量的定义与初始化8、ASCII码和Unicode编码9、转义字符10、类型转换11、常量 三、Java运算符1、算术运算符2、赋值运算符3、关系运算符4、逻辑运算符5、…

东莞酷得智能 AC63系列单片机

目前AC63芯片系列有下型号&#xff1a; AC6323A2&#xff1a;封装QFN20 AC6366C4&#xff1a;封装QFN32 AC6368A2&#xff1a;封装SOP8 AC63系列 SoC 芯片支持以下特性 蓝牙双模&#xff08;支持蓝牙EDR、蓝牙BLE5.2) 超低功耗处理器 数传透传智能设备 支持低功耗R…

Day16_学点儿JavaEE_理论知识_Tomcat、JSP、Servlet

1 软件的结构 C/S (Client - Server 客户端-服务器端) 典型应用&#xff1a;QQ软件 &#xff0c;飞秋&#xff0c;印象笔记。 特点&#xff1a; 必须下载特定的客户端程序。服务器端升级&#xff0c;客户端升级。 B/S &#xff08;Broswer -Server 浏览器端- 服务器端&…

尚硅谷html5+css3(2)CSS5基本知识

1.网页分为三个部分&#xff1a; 结构&#xff1a;HTML 表现&#xff1a;CSS 行为JavaScript CSS:层叠样式表&#xff0c;网页实际上是一个多层结构&#xff0c;通过CSS可以分别为网页的每一个层来设置样式&#xff0c;最终用户只看最上面的一层&#xff0c;总之&#xff0…

《MATLAB科研绘图与学术图表绘制从入门到精通》

解锁MATLAB科研绘图魅力&#xff0c;让数据可视化成为你的科研利器&#xff01; 1.零基础快速入门&#xff1a;软件操作实战案例图文、代码结合讲解&#xff0c;从入门到精通快速高效。 2.多种科研绘图方法&#xff1a;科研绘图基础变量图形极坐标图形3D图形地理信息可视化等&a…

4月7号总结

java学习 一.正则表达式 定义&#xff1a;正则表达式是一种用于描述字符串模式的表达式&#xff0c;通常被用于文本搜索、匹配和替换。它是一种强大的工具&#xff0c;可以在文本处理和文本分析中进行复杂的匹配和操作。 通过字符串引用里面的方法matches&#xff0c;然后执行…

转让名称带中国的金融控股集团公司要多少钱

随着公司的发展和市场竞争的影响&#xff0c;越来越多的创业者希望注册一家好名称的公司&#xff0c;以提高企业知名度和竞争力。但是&#xff0c;注册中字头无地域公司需要满足一定的条件和流程。本文将对中字头无地域公司注册条件及流程进行详细的介绍。可以致电咨询我或者来…

Linux IO:打开数据之窗的魔法

Linux I/O&#xff08;输入/输出&#xff09;是操作系统中一个至关重要的组成部分&#xff0c;它涉及到数据在内存&#x1f9e0;、存储设备&#x1f4be;、网络接口&#x1f310;等之间的传输过程。在Linux中&#xff0c;I/O操作不仅仅是文件读写那么简单&#xff0c;它包括了一…