springCloudAlibaba之服务熔断组件---sentinel

news2024/12/28 19:56:45

sentinel组件学习

  • sentinel学习
    • sentinel容错机制
    • 使用代码方式进行QPS流控-流控规则初体验
      • 使用@SentinelResource注解进行流控
    • 通过代码方式设置降级规则-降级规则初体验
    • sentinel控制台部署
      • 客户端整合服务端
    • springcloud整合sentinel
      • QPS流控规则
      • 并发线程数-流控规则
      • BlockExceptionHandler统一异常处理,此时可以不加@SentinelResource注解
      • 关联流控模式
      • 链路流控模式
    • 流控效果介绍
      • 预热流控效果
      • 排队等待
    • 熔断降级规则
    • sentinel-整合openfeign降级
      • 消费端feing调用
    • 热点参数流控
    • sentinel规则持久化
      • 基于Nacos配置中心控制台实现推送

sentinel学习

  • 服务雪崩

服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。
在这里插入图片描述

sentinel容错机制

常见的容错机制有超时机制、服务限流、隔离、服务熔断

  • 超时机制
    在不做任何处理的情况下,服务提供者不可用回导致消费者请求线程强制等待,而造成系统资源耗尽。加入超时机制,一旦超时,就释放资源。由于释放资源较快,一定程度上可以抑制资源耗尽的问题。
  • 服务限流
    某个服务达到QPS设定最大值则抛异常。
  • 服务熔断
    在这里插入图片描述
  • 服务降级
    有服务熔断,必然要有服务降级。
    所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fellback(回退),回调,返回一个缺省值。例如:(备用接口/缓存/mock数据),这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。(服务熔断之后进入客户端降级方法)

使用代码方式进行QPS流控-流控规则初体验

  • 引入sentinel相关包
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--sentinel核心库-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-core</artifactId>
      <version>1.8.0</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>

    <!--sentinel注解方式-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-annotation-aspectj</artifactId>
      <version>1.8.0</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!--sentinel整合dashbaord控制台-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-transport-simple-http</artifactId>
      <version>1.8.0</version>
    </dependency>
  </dependencies>
  • 代码实现
package com.sentinel.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : zhouzhiqiang
 * @date : 2024/6/5 23:25
 * @description :
 */
@Slf4j
@RestController
@RequestMapping("/hello")
public class HelloController {

    private static final String RESOURCE_NAME="hello";
    private static final String USER_RESOURCE_NAME="user";
    private static final String DEGRADE_RESOURCE_NAME="degrade";

    @RequestMapping("/helloSentinel")
    public String hello(){

        Entry entry=null;
        try {
            entry= SphU.entry(RESOURCE_NAME);
            String str="hello world";
            log.info("======="+str+"=======");
            return str;
        } catch (BlockException e) {
            log.info("block");
            return "被限流了!";
        }catch (Exception e){
            Tracer.traceEntry(e,entry);
        }finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }

    @PostConstruct
    public static void initFlowRules(){
        //流控规则
        List<FlowRule> rules=new ArrayList<>();

        //流控
        FlowRule rule = new FlowRule();
        //为哪个资源进行流量控制
        rule.setResource(RESOURCE_NAME);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        //加载流控规则
        FlowRuleManager.loadRules(rules);
    }
}

使用@SentinelResource注解进行流控

要使用这个注解需要引入相关包和配置SentinelResourceAspect的bean

  • 引入包
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-annotation-aspectj</artifactId>
      <version>1.8.0</version>
    </dependency>
  • 配置bean
  @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
  • 使用注解方式

value:定义资源(接口名称)
blockHandler :设置流控降级后的处理方法,默认该方法,必须声明在一个类中
fallback:接口中出现异常了,就可以交给fellback指定的处理方法

@PostConstruct
    public static void initFlowRules(){
        //流控规则
        List<FlowRule> rules=new ArrayList<>();

        //流控
        FlowRule rule = new FlowRule();
        //为哪个资源进行流量控制
        rule.setResource(USER_RESOURCE_NAME);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        //加载流控规则
        FlowRuleManager.loadRules(rules);
    }

    @RequestMapping("/user")
    @SentinelResource(value = USER_RESOURCE_NAME,blockHandler = "blockHandlerForGetUser",fallback = )
    public User getUser(String id){
        return new User("zzq");
    }

    /**
     * 注意:
     * 1、一定是public
     * 2、返回值一定得和原方法返回值一致,包含方法的参数
     * 3、可以在参数的最后添加BlockException,可以区分是什么规则的处理方法
     * @param id
     * @param e
     * @return
     */
    //降级方法
    public User blockHandlerForGetUser(String id,BlockException e){
        e.printStackTrace();
        return new User("被流控了!");
    }

通过代码方式设置降级规则-降级规则初体验

@RestController
@RequestMapping("/test")
public class TestController {

    private static final String DEGRADE_RESOURCE_NAME="degrade";

    @RequestMapping("/degrade")
    @SentinelResource(value = DEGRADE_RESOURCE_NAME,entryType = EntryType.IN,blockHandler = "blockHandlerForJob")
    public User degrade(String id){
        int i=1;
        int sum=i/0;
        return new User("成功");
    }

    public User blockHandlerForJob(String id, BlockException e){
        e.printStackTrace();
        return new User("触发降级规则");
    }

    @PostConstruct
    public void initDegradeRule(){
        List<DegradeRule> rules=new ArrayList<>();

        DegradeRule rule = new DegradeRule();
        rule.setResource(DEGRADE_RESOURCE_NAME);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        //触发熔断异常数
        rule.setCount(2);
        //触发熔断的最小请求数
        rule.setMinRequestAmount(2);
        //统计时长:单位ms  1分钟
        rule.setStatIntervalMs(60*1000);
        //一分钟内:执行了两次 ,出现两次异常 就会触发熔断

        /**
         * 熔断持续时间,单位秒。一旦触发了熔断,再次请求接口则直接调用降级方法。
         * 10秒后,---半开状态,恢复接口调用。如果再次请求,则会熔断,不再根据熔断规则进入熔断,而是直接进入熔断
         */
        rule.setTimeWindow(10);


        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

流控规则一般设置在服务生产方,而降级规则一般设置在服务消费方

sentinel控制台部署

下载dashboard--https://github.com/alibaba/Sentinel/releases

运行jar包:java -jar sentinel-dashboard-1.8.0.jar。运行完毕进行访问,默认端口号8080。用户名和密码默认sentinel
在这里插入图片描述

客户端整合服务端

客户端需要引入Transport模块来与sentinel控制台进行通信

<!--sentinel整合dashbaord控制台-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-transport-simple-http</artifactId>
      <version>1.8.0</version>
    </dependency>
  • 配置启动
    客户端启动时需要加入JVM参数-Dcsp.sentinel.dashboard.server=192.168.1.15:8080,指定控制台地址和端口
    在这里插入图片描述

springcloud整合sentinel

  • 添加依赖
     <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  • yaml配置文件
server:
  port: 8081
spring:
  application:
    name: order-sentinel
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.184.15:8080
        port: 8719
        client-ip: 192.168.184.1

在虚拟机上部署dashboard的时候,主机和虚拟机一直网络不通,解决方法:
1、关闭本机和虚拟机的防火墙
在这里插入图片描述
2、本机不动,配置虚拟机ip,网段和本地vmnet8保持一致,网关查看虚拟网络编辑器
在这里插入图片描述

ONBOOT="yes"
IPADDR="192.168.184.15"
NETMASK="255.255.255.0"
GATEWAY="192.168.184.2"
DNS1="8.8.8.8"
DNS2="8.8.4.4"

3、最重要的一步,设置网络连接模式为net模式
在这里插入图片描述
原因:解释: 1:当我们安装VMware Workstation后,在宿主机(物理电脑)上会多出两个网卡,VMNet1、VMNet8。 2:vmnet1是为host-only方式服务的,vmnet8是为NAT方式服务的

QPS流控规则

添加流控规则:QPS为2,超过2触发流控降级
在这里插入图片描述
在这里插入图片描述

  • 代码中指定自定义降级方法,dashboard定义流控规则,代码自定义降级方法
    /**
     * 流控测试接口
     * @return
     */
    @RequestMapping("/flow")
    @SentinelResource(value = "flow",blockHandler = "blockHandlerForFlow")
    public String flow(){
        return "正常访问";
    }

    public String blockHandlerForFlow(BlockException e){
        e.printStackTrace();
        System.out.println("触发流控,快速失败");
        return "触发流控,快速失败";
    }

并发线程数-流控规则

  • dashboard配置
    在这里插入图片描述
  • 代码
    @RequestMapping("/flowThread")
    @SentinelResource(value = "flowThread",blockHandler = "blockHandlerForFlow")
    public String flowThread(){
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "正常访问";
    }

    public String blockHandlerForFlow(BlockException e){
        e.printStackTrace();
        System.out.println("触发流控,快速失败");
        return "触发流控,快速失败";
    }
  • 测试
    开两个浏览器模拟两个线程
  • 测试结果
    在这里插入图片描述

BlockExceptionHandler统一异常处理,此时可以不加@SentinelResource注解

  • 代码
@Data
public class Result <T>{
    private Integer code;
    private String msg;
    private T data;

    public Result(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Result(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static Result error(Integer code,String msg){
        return new Result(code,msg);
    }
}
@Component
@Slf4j
public class MyBlockExceptionHandler implements BlockExceptionHandler {

    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
        //规则的详细信息
        log.info("BlockExceptionHandler BlockException=============="+e.getRule());
        Result r = null;
        if (e instanceof FlowException) {
            r=Result.error(100,"接口被限流了!");
        }else if (e instanceof DegradeException){
            r=Result.error(101,"服务降级了!");
        }else if (e instanceof ParamFlowException){
            r=Result.error(102,"热点参数限流了!");
        }else if (e instanceof SystemBlockException){
            r=Result.error(103,"触发系统保护规则!");
        }else if (e instanceof AuthorityException){
            r=Result.error(104,"授权规则不通过!");
        }

        response.setStatus(500);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(response.getWriter(),r);
    }
}
  • 测试代码
    此时在dashboar的为这个接口设置流控规则后,可以看到设置的同一异常起效果了
 @RequestMapping("/exceptionHandler")
    public String exceptionHandler(){
        return "正常访问";
    }

关联流控模式

流控模式有三种直接、关联、链路
在这里插入图片描述

关联模式:当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写的速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢。

  • dashboard设置
    当生成订单QPS>=2的时候,查询订单接口就被限流
    在这里插入图片描述
  • 代码
 @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功");
        return "生成订单";
    }

    @RequestMapping("/get")
    public String get(){
        return "查询订单";
    }
  • 生成接口和查询接口测试
    生成接口和查询接口不好一起测试,生成接口使用apifox进行压测,查询接口手动点
    在这里插入图片描述
  • 测试结果
    查询接口触发流控规则
    在这里插入图片描述
  • 或者使用JMeter去做压测
    在这里插入图片描述
    在这里插入图片描述

链路流控模式

可以对资源进行流控
在这里插入图片描述

  • 代码
public interface IUserService {
    User getUser();
}

对getUser添加@SentinelResource注解

@Service
public class IUserServiceImpl implements IUserService{

    @SentinelResource(value = "getUser",blockHandler = "blockHandlerForUser")
    public User getUser() {
        User user = new User();
        user.setId("001");
        user.setName("针对业务方法进行流控");
        return user;
    }

    public User blockHandlerForUser(BlockException e){
        e.printStackTrace();
        User user = new User();
        user.setId("001");
        user.setName("ddddd");
        return new User();
    }
}

test1和test2调用getUser(),当getUser(),达到QPS2的时候,对test1或者test2做流控

@RestController
@RequestMapping("/link")
public class LinkController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/test1")
    public User test1(){
        return userService.getUser();
    }

    @RequestMapping("/test2")
    public User test2(){
        return userService.getUser();
    }
}
  • 配置文件配置
    web-context-unify: false # 默认将调用链路收敛了
server:
  port: 8081
spring:
  application:
    name: order-sentinel
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.184.15:8080
        port: 8719
        client-ip: 192.168.184.1
      web-context-unify: false  # 默认将调用链路收敛了
  • dashboar配置
    在这里插入图片描述
  • 测试结果
    当test1qps达到2的时候触发流控
    在这里插入图片描述

流控效果介绍

流控效果有快速失败、预热、排队等待。预热:适用于激增流量的情况
在这里插入图片描述

预热流控效果

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

  • dashboard配置
    qps最大为10,10秒内达到10
    在这里插入图片描述

排队等待

激增流量:长时间处于低水平,某个时间段处于高水平,可以使用预热的方式进行处理。

脉冲流量:一段时间处于低水平某个时刻到达高水平,然后又变为低水平,循环往复

匀速排队:严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过

  • 测试
    设置流控效果为快速失败,单机QPS阈值为5,使用JMeter测试,一秒执行10次循环5次
    在这里插入图片描述
    在这里插入图片描述
    测试结果:可以看到一秒内10个QPS5个通过,5个拒绝
    在这里插入图片描述
  • 使用排队等待流控效果
    dashboard配置:单机阈值5,超时时间5秒。比如有10个线程,每次进去5个,其他5个等待。执行完一个进去一个,如果5个线程在5秒内没有执行完则直接拒绝
    在这里插入图片描述
  • 测试结果
    所有请求都执行成功
    在这里插入图片描述

熔断降级规则

慢调用比例:慢调用占调用总数的比例

  • dashboard配置
    最大RT:单位毫秒,不能超过1秒,超过1秒则触发降级。比例阈值:慢调用占请求次数的比例。最小请求数:配合比例阈值,10次请求有一次触发慢调用则触发降级
    在这里插入图片描述
  • 使用Jmetter进行测试
    在这里插入图片描述
  • 测试结果
    触发降级
    在这里插入图片描述

sentinel-整合openfeign降级

nacos服务注册必须是一个web项目
按此步骤完成微服务搭建后,发现服务并没有注册到nacos注册中心,在官方文档查看springboot和springcloud版本也并没有冲突,尝试引入nacos管理依赖后还是不行,最后想到要在nacos注册中心注册的微服务应该必须是一个web项目,而在springboot环境下开发web项目需要引入springMvc的相关启动依赖,加上后发现服务成功注册到了nacos注册中心

  • 在消费端引入依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
  • 消费端配置yml
    特别加上:server: port: 8084 spring: application: name: product-service cloud: nacos: username: zzq password: 1w2e3r4! server-addr: 192.168.184.15:8848 discovery: namespace: 31a14d31-cda4-4a37-a4ba-7717aaddd97d feign: sentinel: enabled: true
server:
  port: 8084
spring:
  application:
    name: product-service
  cloud:
    nacos:
      username: zzq
      password: 1w2e3r4!
      server-addr: 192.168.184.15:8848
      discovery:
        namespace: 31a14d31-cda4-4a37-a4ba-7717aaddd97d
feign:
  sentinel:
    enabled: true

消费端feing调用

  • feing
@FeignClient(value = "stock-service",path = "/person",fallback = IPersonServiceFallback.class)
public interface IPersonService {

    @RequestMapping("/getPerson")
    public Person getPerson();
}

必须要有一个feingclint的实现类,并且注入进spring

@Component
public class IPersonServiceFallback implements IPersonService {
    public Person getPerson() {
        Person person = new Person();
        person.setId("001");
        person.setName("未找到用户");
        return person;
    }
}

消费端调用服务端

   @RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private IPersonService personService;

    @RequestMapping("/getProduct")
    public String getProduct(){
        Person person = personService.getPerson();
        return "调用成功:"+person.getName();
    }
}

  • 测试结果
    调用异常执行降级方法
    在这里插入图片描述

热点参数流控

场景:接口参数对某些值的访问QPS比其他高。典型的电商系统中,商品查询接口,某些商品的访问QPS要远远高于其他商品,比如商品ID为1的商品,访问请求远远高于其他商品。

  • dashboard配置
    在这里插入图片描述

sentinel规则持久化

在这里插入图片描述
结合nacos配置中心使用推模式进行规则的持久化

基于Nacos配置中心控制台实现推送

  • 引入依赖
  <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
   </dependency>

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

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

相关文章

wooyun_2015_110216-Elasticsearch-vulfocus

1.原理 ElasticSearch具有备份数据的功能&#xff0c;用户可以传入一个路径&#xff0c;让其将数据备份到该路径下&#xff0c;且文件名和后缀都可控。 所以&#xff0c;如果同文件系统下还跑着其他服务&#xff0c;如Tomcat、PHP等&#xff0c;我们可以利用ElasticSearch的备…

群体优化算法----火山爆发算法介绍以及离散优化Pareto最优解示例

介绍 火山爆发算法&#xff08;Volcano Eruption Algorithm&#xff0c;VEA&#xff09;是一种新兴的群智能优化算法&#xff0c;其灵感来源于火山爆发的自然现象。火山爆发算法模拟了火山爆发过程中熔岩流动和喷发的行为&#xff0c;以寻找全局最优解。这种算法利用了火山爆发…

全网短剧资源

热门短剧资源库&#xff0c;已更新了 9000&#xff0c;记得收藏&#xff1a;https://www.kdocs.cn/l/ciptAICGdWYz

ABB机械人模型下载

可以下载不同格式的 https://new.abb.com/products/robotics/zh/robots/articulated-robots/irb-6700 step的打开各部件是分开的&#xff0c;没有装配在一起&#xff0c;打开看单个零件时&#xff0c;我们会发现其各零件是有装配的定位关系的。 新建一个装配环境&#xff0c;点…

武忠祥17堂课没必要全听,这几个才是精华!

作者&#xff1a;Captain 链接&#xff1a;https://www.zhihu.com/question/381665751/answer/3197724055 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 17堂课类似于习题课&#xff0c;是专题训练 17堂课省略了…

基于AI大文本模型的智慧对话开发设计及C#源码实现,实现智能文本改写与智慧对话

文章目录 1.AI 大模型发展现状2.基于AI服务的智慧对话开发2.1 大模型API选择2.2 基于C#的聊天界面开发2.3 星火大模型API接入2.4 优化开发界面与显示逻辑 3.源码工程Demo及相关软件下载参考文献 1.AI 大模型发展现状 端午假期几天&#xff0c;关注到国内的AI大模型厂商近乎疯狂…

6.7.29 基于卷积神经网络的乳腺良恶性图像分类

计算机化乳腺癌诊断系统在早期癌症诊断中发挥着重要作用。为此&#xff0c;应用深度学习&#xff0c;利用卷积神经网络 (CNN) 对基于小型乳房 X 线图像分析协会 (mini-MIAS) 数据库的乳房 X 线图像中的异常&#xff08;良性或恶性&#xff09;进行分类。观察准确度、灵敏度和特…

java之基础2笔记

1 类型转换 1.1 自动类型转换&#xff08;隐式类型转换&#xff09; 从小的数据类型到大的数据类型的转换&#xff08;如 int 到 long&#xff09;。 从低精度的数据类型到高精度的数据类型的转换&#xff08;如 float 到 double&#xff09;。 1.2 强制类型转换&#xff0…

逆序队专题

逆序对的定义是&#xff0c;在一个数组中&#xff0c;对于下标 ( i ) 和 ( j )&#xff08;其中 ( i < j )&#xff09;&#xff0c;如果 ( a[i] > a[j] )&#xff0c;则称 ((a[i], a[j])) 为数组的一个逆序对。 换句话说&#xff0c;逆序对就是在数组中前面的元素大于后…

每日十题---三

1. Vue中$nextTick原理 1. 简单的理解就是它就是一个setTimeout函数&#xff0c;将函数放到异步后去处理。 2. Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化&#xff0c;Vue 将开启一个队列&#xff0c;并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被…

【计算机毕业设计】273基于微信小程序的刷题系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

AI日报0610 -- Prompt这样改,AI成本瞬降20%!

全球首届人工智能选美大赛 世界 AI 创作者大赛和创作者平台 FanVue 正在举办首届“Miss AI”大赛 超过 1,500 名 AI 生成的模特竞逐。这些模型不仅形象逼真 还展示了不同的个性和原因。 评委将评估技术和吸引观众的能力。 奖金池高达 20,000 美元&#xff0c;并有机会参加公关…

讨论C++类与对象

讨论C类与对象 C语言结构体和C类的对比类的实例化类对象的大小猜想一猜想二针对上述猜想的实践 this指针不同对象调用成员函数 类的6个默认成员函数构造函数析构函数拷贝构造函数浅拷贝和深拷贝 赋值运算符重载 初始化列表初始化顺序 C语言结构体和C类的对比 在C语言中&#x…

require.context()函数介绍

业务需求&#xff1a; 前端Vue项目怎样读取src/assets目录下所有jpg文件 require.context()方法来读取src/assets目录下的所有.jpg文件 <template><div><img v-for"image in images" :src"image" :key"image" /></div> …

Vision-LSTM: xLSTM 作为通用视觉主干

摘要 尽管Transformer最初是为自然语言处理引入的&#xff0c;但它现在已经被广泛用作计算机视觉中的通用主干结构。最近&#xff0c;长短期记忆&#xff08;LSTM&#xff09;已被扩展为一种可扩展且性能优越的架构——xLSTM&#xff0c;它通过指数门控和可并行化的矩阵内存结…

用函数指针求a和b中的大者

指针变量也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个函数入口地址就称为函数的指针。可以用一个指针变量指向函数&#xff0c;然后通过该指针变量调用此函数。 先按一般方法编写程序&#xff1a; 可以用一个指针变量指向max函数&#xff0c;然后通过该指…

不能访问huggingface、与GPU配置

不能访问huggingface解决方法 如果是从 huggingface.co 下载模型&#xff0c;由于国内不能访问&#xff0c;所以建议先配置一下环境变量&#xff0c; 通过访问国内镜像站点 https://hf-mirror.com来下载模型。 &#xff08;1&#xff09;Linux系统设置环境变量&#xff1a; e…

STM32引脚外部中断和外部事件模式的区别

STM32引脚外部中断和外部事件模式的区别 STM32引脚模式外部中断和外部事件模式的区别&#xff1a; (以 GPIO_MODE_IT_FALLING 和 GPIO_MODE_EVT_FALLING 为例) GPIO_MODE_IT_FALLING 能够触发中断&#xff0c;用在中断方式编程。GPIO_MODE_EVT_FALLING 只设置中断标志位&…

vue3 基于el-tree增加、删除节点(非TypeScript 写法)

话不多说&#xff0c;直接贴代码 <template><div class"custom-tree-container"><!-- <p>Using render-content</p><el-tree style"max-width: 600px" :data"dataSource" show-checkbox node-key"id" …

【C语言初阶】分支语句

&#x1f31f;博主主页&#xff1a;我是一只海绵派大星 &#x1f4da;专栏分类&#xff1a;C语言 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、什么是语句 二、if语句 悬空else 三、switch语句 default 四、switch语句与if-else语句性能对比如何&#xff1f…