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.mzph.cn/news/798912.shtml

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

相关文章

最新高自定义化的AI翻译(沉浸式翻译),可翻译网页和PDF等文件或者文献(附翻译API总结,Deeplx的api,Deepl的api)

前序 常见问题&#xff1a; 1.有时候想翻译网页&#xff0c;又翻译文献怎么办&#xff1f;下两个软件&#xff1f; 2.什么软件可以翻译视频字幕&#xff1f; 3.什么软件可以翻译PDF文件&#xff1f; 沉浸式翻译介绍 可以翻译文献可以翻译视频字幕可以翻译PDF文件支持OpenAI翻译…

Linux中shell脚本的学习第一天,编写脚本的规范,脚本注释、变量,特殊变量的使用等,包含面试题

4月7日没参加体侧的我自学shell的第一天 Shebang 计算机程序中&#xff0c;shebang指的是出现在文本文件的第一行前两个字符 #&#xff01; 1)以#!/bin/sh 开头的文件&#xff0c;程序在执行的时候会调用/bin/sh, 也就是bash解释器 2)以#!/usr/bin/python 开头的文件&#…

uniapp极光推送、java服务端集成

一、准备工作 1、进入【服务中心】-【开发者平台】 2、【创建应用】&#xff0c;填写应用名称和图标&#xff08;填写项目名称&#xff0c;项目logo就行&#xff0c;也可填写其他的&#xff09; 3、选择【消息推送】服务&#xff0c;点击下一步 ​ ​ Demo测试 参照文档&…

论文阅读《Semantic Prompt for Few-Shot Image Recognition》

论文地址&#xff1a;https://arxiv.org/pdf/2303.14123.pdf 论文代码&#xff1a;https://github.com/WentaoChen0813/SemanticPrompt 目录 1、存在的问题2、算法简介3、算法细节3.1、预训练阶段3.2、微调阶段3.3、空间交互机制3.4、通道交互机制 4、实验4.1、对比实验4.2、组…

【C++】哈希思想的应用(位图、布隆过滤器)及海量数据处理方法

文章目录 前言位图什么是位图简单实现一个自己的位图位图的应用场景 布隆过滤器位图的缺陷及布隆过滤器的提出布隆过滤器的概念简单实现一个自己的布隆过滤器布隆过滤器的优缺点布隆过滤器的应用场景 海量数据处理 前言 哈希思想的在实际中的应用除了哈希表这个数据结构之外还…

【Redis 知识储备】读写分离/主从分离架构 -- 分布系统的演进(4)

读写分离/主从分离架构 简介出现原因架构工作原理技术案例架构优缺点 简介 将数据库读写操作分散到不同的节点上, 数据库服务器搭建主从集群, 一主一从, 一主多从都可以, 数据库主机负责写操作, 从机只负责读操作 出现原因 数据库成为瓶颈, 而互联网应用一般读多写少, 数据库…

C++的List类(一):List类的基本概念

目录 前言 List类的基本概念 List的构造函数 List类迭代器的使用 List的功能 List的元素访问 List与vector比较 前言 vector的insert和erase都会导致迭代器失效list的insert不会导致迭代器失效&#xff0c;erase会导致迭代器失效 insert导致失效的原因是开辟了新空间后…

Visual Studio 2022-C语言如何防止头文件多次引入

头文件的包含 本地⽂件包含 #include "filename" 查找策略&#xff1a;先在源⽂件所在⽬录下查找&#xff0c;如果该头⽂件未找到&#xff0c;编译器就像查找库函数头⽂件⼀样在 标准位置查找头⽂件。 如果找不到就提⽰编译错误。 Linux环境的标准头⽂件的路径&…

如何自定义项目启动时的图案

说明&#xff1a;有的项目启动时&#xff0c;会在控制台输出下面的图案。本文介绍Spring Boot项目如何自定义项目启动时的图案&#xff1b; 生成字符图案 首先&#xff0c;找到一张需要设置的图片&#xff0c;使用下面的代码&#xff0c;将图片转为字符文件&#xff1b; impo…

【Unity每日一记】鼠标相关API

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

Linux初学(十七)redis

一、简介 redis就是一个内存数据库 redis中的数据&#xff0c;都是保存在内存中 端口&#xff1a;6379 二、安装redis 方法一&#xff1a;编译安装 方法二&#xff1a;yum安装-epel 第一步&#xff1a;配置epel源 详见&#xff1a;http://t.csdnimg.cn/AFl1K第二步&#xff1a…

GaN肖特基势垒二极管(SBD)的多阴极应用建模与参数提取

GaN Schottky Barrier Diode (SBD) Modeling and Parameter Extraction for Multicathode Application&#xff08;TED 24年&#xff09; 摘要 本文提出了一种适用于多阴极应用的紧凑型可扩展GaN肖特基二极管大信号模型。详细给出了外在和内在模型参数的可扩展规则。实验和理…

Stm32 HAL库 访问内部flash空间

Stm32 HAL库 访问内部flash空间 代码的部分串口配置申明文件main函数 在一些时候&#xff0c;需要存储一些数据&#xff0c;但是又不想接外部的flash&#xff0c;那我们可以知道&#xff0c;其实还有内部的flash可以使用&#xff0c; 需要注意的是内部flash&#xff0c;读写次数…

书生浦语训练营二期第三次作业

文章目录 基础作业1. 在茴香豆 Web 版中创建自己领域的知识问答助手第一轮对话第二轮对话第三轮对话第四轮对话第五轮对话 2.在 InternLM Studio 上部署茴香豆技术助手修改配置文件创建知识库运行茴香豆知识助手 基础作业 1. 在茴香豆 Web 版中创建自己领域的知识问答助手 我…

神经网络中的超参数调整

背景 在深度神经网络学习和优化中&#xff0c;超参数调整一项必备技能&#xff0c;通过观察在训练过程中的监测指标如损失loss和准确率来判断当前模型处于什么样的训练状态&#xff0c;及时调整超参数以更科学地训练模型能够提高资源利用率。在本研究中使用了以下超参数&#x…

iOS 17.5系统或可识别并禁用未知跟踪器,苹果Find My技术应用越来越合理

苹果公司去年与谷歌合作&#xff0c;宣布将制定新的行业标准来解决人们日益关注的跟踪器隐私问题。苹果计划在即将发布的 iOS 17.5 系统中加入这项提升用户隐私保护的新功能。 科技网站 9to5Mac 在苹果发布的 iOS 17.5 开发者测试版内部代码中发现了这项反跟踪功能的蛛丝马迹…

XML HTTP传输 小结

what’s XML XML 指可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;。 XML 被设计用来传输和存储数据&#xff0c;不用于表现和展示数据&#xff0c;HTML 则用来表现数据。 XML 是独立于软件和硬件的信息传输工具。 应该掌握的基础知识 HTMLJavaScript…

使用pytorch构建有监督的条件GAN(conditional GAN)网络模型

本文为此系列的第四篇conditional GAN&#xff0c;上一篇为WGAN-GP。文中在无监督的基础上重点讲解作为有监督对比无监督的差异&#xff0c;若有不懂的无监督知识点可以看本系列第一篇。 原理 有条件与无条件 如图投进硬币随机得到一个乒乓球的例子可以看成是一个无监督的GAN&…

从0到1搭建文档库——sphinx + git + read the docs

sphinx git read the docs 目录 一、sphinx 1 sphinx的安装 2 本地构建文件框架 1&#xff09;创建基本框架&#xff08;生成index.rst &#xff1b;conf.py&#xff09; conf.py默认内容 index.rst默认内容 2&#xff09;生成页面&#xff08;Windows系统下&#xf…

实战webSocket压测(三)Jmeter真实接口联调

背景&#xff1a; 接口地址为&#xff1a;ws://sunlei.demo 接口说明&#xff1a;websocket接口&#xff0c;首次连接&#xff0c;通过Text请求设置开启标志&#xff0c;然后通过wav文件流传输&#xff0c;达到后端服务可以根据传输信息进行解析满足指定标准后&#xff0c;web…