Spring Cloud之服务熔断与降级(Hystrix)
目录
Hystrix
概念
作用
服务降级
简介
使用场景
接口降级
服务端服务降级
1.添加依赖
2.定义接口
3.实现接口
4.Controller类使用
5.启动类添加注释
6.浏览器访问
客户端服务降级
1.添加依赖
2.application.yml 中添加配置
3.定义接口
4.Controller类使用
5.appliction.yml 中添加配置,在客户端配置请求超时的时间
6.启动类添加注释
7.浏览器访问
全局降级
1.注解配置
2.创建方法
3.业务方法标注注解
4.浏览器访问
服务熔断
简介
熔断参数设置
熔断类型
熔断打开
熔断关闭
熔断半开
熔断机制
使用步骤
示例
1.定义接口
2.实现接口
3.方法对外提供服务
4.浏览器访问
故障监控
在微服务架构中,一个应用往往由多个服务组成,这些服务之间相互依赖,依赖关系错综复杂。
当服务 E 发生故障或网络延迟时,会出现以下情况:
1.即使其他所有服务都可用,由于服务 E 的不可用,那么用户请求 1、2、3 都会处于阻塞状态,等待服务 E 的响应。在高并发的场景下,会导致整个服务器的线程资源在短时间内迅速消耗殆尽
2.所有依赖于服务 E 的其他服务,例如服务 B、D 以及 F 也都会处于线程阻塞状态,等待服务 E 的响应,导致这些服务的不可用
3.所有依赖服务B、D 和 F 的服务,例如服务 A 和服务 C 也会处于线程阻塞状态,以等待服务 D 和服务 F 的响应,导致服务 A 和服务 C 也不可用
当微服务系统的一个服务出现故障时,故障会沿着服务的调用链路在系统中疯狂蔓延,最终导致整个微服务系统的瘫痪,这就是“雪崩效应”。为了防止此类事件的发生,微服务架构引入了“熔断器”的一系列服务容错和保护机制。
Hystrix
概念
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,可以保证一个服务出现故障时,不会导致整个系统出现雪崩效应,以提高分布式系统的弹性。
作为“断路器”,在一个服务出现故障时,可以通过短路器监控,返回一个可以处理的响应结果,保证服务调用线程不会被长时间占用,避免故障蔓延。
作用
保护线程资源:防止单个服务的故障耗尽系统中的所有线程资源
快速失败机制:当某个服务发生了故障,不让服务调用方一直等待,而是直接返回请求失败
提供降级(FallBack)方案:在请求失败后,提供一个设计好的降级方案,通常是一个兜底方法,当请求失败后即调用该方法
防止故障扩散:使用熔断机制,防止故障扩散到其他服务
监控功能:提供熔断器故障监控组件 Hystrix Dashboard,随时监控熔断器的状态
服务降级
简介
服务出现故障时,给故障服务降级到事先准备好的故障处理结果,将此结果返回给服务消费者;
如:
客户端访问服务1,服务1调用服务2,服务2出现故障,Hystrix服务降级,返回一个可以处理的结果给服务1,服务1再以友好的错误界面返回给客户端
使用场景
1.在服务器压力剧增时,根据实际业务情况及流量,对一些不重要、不紧急的服务进行有策略地不处理或简单处理,从而释放服务器资源以保证核心服务正常运作。
2.当某些服务不可用时,为了避免长时间等待造成服务卡顿或雪崩效应,而主动执行备用的降级逻辑立刻返回一个友好的提示,以保障主体业务不受影响
接口降级
服务端服务降级
1.添加依赖
<!--hystrix 依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
2.定义接口
public interface DeptService {// hystrix 熔断器示例 okpublic String deptInfo_Ok(Integer id);//hystrix 熔断器超时案例public String deptInfo_Timeout(Integer id);
}
3.实现接口
@Service("deptService")
public class DeptServiceImpl implements DeptService {@Overridepublic String deptInfo_Ok(Integer id) {return "线程池:" + Thread.currentThread().getName() + " deptInfo_Ok,id: " + id;}//一旦该方法失败并抛出了异常信息后,会自动调用 @HystrixCommand 注解标注的 fallbackMethod 指定的方法@HystrixCommand(fallbackMethod = "dept_TimeoutHandler",commandProperties =//规定 5 秒钟以内就不报错,正常运行,超过 5 秒就报错,调用指定的方法{@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")})@Overridepublic String deptInfo_Timeout(Integer id) {int outTime = 6;try {TimeUnit.SECONDS.sleep(outTime);} catch (InterruptedException e) {e.printStackTrace();}return "线程池:" + Thread.currentThread().getName() + " deptInfo_Timeout,id: " + id + " 耗时: " + outTime;}// 当服务出现故障后,调用该方法给出友好提示public String dept_TimeoutHandler(Integer id) {return "C语言中文网提醒您,系统繁忙请稍后再试!"+"线程池:" + Thread.currentThread().getName() + " deptInfo_Timeout,id: " + id;}
}
@HystrixCommand 注解:
参数 fallbackMethod 属性用于指定降级方法
参数 execution.isolation.thread.timeoutInMilliseconds 用于设置自身调用超时时间的峰值,峰值内可以正常运行,否则执行降级方法
4.Controller类使用
@RestController
@Slf4j
public class DeptController {@Autowiredprivate DeptService deptService;@Value("${server.port}")private String serverPort;@RequestMapping(value = "/dept/hystrix/ok/{id}")public String deptInfo_Ok(@PathVariable("id") Integer id) {String result = deptService.deptInfo_Ok(id);log.info("端口号:" + serverPort + " result:" + result);return result + ", 端口号:" + serverPort;}// Hystrix 服务超时降级@RequestMapping(value = "/dept/hystrix/timeout/{id}")public String deptInfo_Timeout(@PathVariable("id") Integer id) {String result = deptService.deptInfo_Timeout(id);log.info("端口号:" + serverPort + " result:" + result);return result + ", 端口号:" + serverPort;}
}
5.启动类添加注释
@SpringBootApplication
@EnableEurekaClient //开启 Eureka 客户端功能
@EnableCircuitBreaker //激活熔断器功能
public class MicroServiceCloudProviderDeptHystrix8004Application {public static void main(String[] args) {SpringApplication.run(MicroServiceCloudProviderDeptHystrix8004Application.class, args);}
}
6.浏览器访问
客户端服务降级
通常情况下,我们都会在客户端进行服务降级,当客户端调用的服务端的服务不可用时,客户端直接进行服务降级处理,避免其线程被长时间、不必要地占用
1.添加依赖
<!--hystrix 依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.application.yml 中添加配置
application.yml 中添加以下配置,开启客户端的 Hystrix 功能
feign:hystrix:enabled: true #开启客户端 hystrix
3.定义接口
@Component
@FeignClient(value = "MICROSERVICECLOUDPROVIDERDEPTHYSTRIX")
public interface DeptHystrixService {@RequestMapping(value = "/dept/hystrix/ok/{id}")public String deptInfo_Ok(@PathVariable("id") Integer id);@RequestMapping(value = "/dept/hystrix/timeout/{id}")public String deptInfo_Timeout(@PathVariable("id") Integer id);
}
4.Controller类使用
@Slf4j
@RestController
public class HystrixController_Consumer {@Resourceprivate DeptHystrixService deptHystrixService;@RequestMapping(value = "/consumer/dept/hystrix/ok/{id}")public String deptInfo_Ok(@PathVariable("id") Integer id) {return deptHystrixService.deptInfo_Ok(id);}//在客户端进行降级@RequestMapping(value = "/consumer/dept/hystrix/timeout/{id}")@HystrixCommand(fallbackMethod = "dept_TimeoutHandler") //为该请求指定专属的回退方法public String deptInfo_Timeout(@PathVariable("id") Integer id) {String s = deptHystrixService.deptInfo_Timeout(id);log.info(s);return s;}// deptInfo_Timeout方法的 专用 fallback 方法public String dept_TimeoutHandler(@PathVariable("id") Integer id) {log.info("deptInfo_Timeout 出错,服务已被降级!");return "C语言中文网提醒您:服务端系统繁忙,请稍后再试!(客户端 deptInfo_Timeout 专属的回退方法触发)";}
}
5.appliction.yml 中添加配置,在客户端配置请求超时的时间
######################### Ribbon 客户端超时控制 ###################################
ribbon:ReadTimeout: 6000 #建立连接所用的时间,适用于网络状况正常的情况下,两端两端连接所用的时间ConnectionTimeout: 6000 #建立连接后,服务器读取到可用资源的时间
######################配置请求超时时间##########################
hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 7000
####################配置具体方法超时时间 为 3 秒########################DeptHystrixService#deptInfo_Timeout(Integer):execution:isolation:thread:timeoutInMilliseconds: 3000
注意:
1.Hystrix 可以来为所有请求(方法)设置超时时间(单位为毫秒),若请求超时则触发全局的回退方法进行处理
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=mmm
2.Hystrix 还可以为某个特定的服务请求(方法)设置超时时间
hystrix.command.xxx#yyy(zzz).execution.isolation.thread.timeoutInMilliseconds=mmm
格式说明如下:
- xxx:为包含该服务方法的类的名称(通常为服务绑定接口的名称),例如 DeptHystrixService 接口。
- yyy:服务方法名,例如 deptInfo_Timeout() 方法。
- zzz:方法内的参数类型,例如 Integer、String 等等
- mmm:要设置的超时时间,单位为毫秒(1 秒 =1000 毫秒)
6.启动类添加注释
@SpringBootApplication
@EnableFeignClients //开启 OpenFeign 功能
@EnableHystrix //启用 Hystrix
public class MicroServiceCloudConsumerDeptFeignApplication {public static void main(String[] args) {SpringApplication.run(MicroServiceCloudConsumerDeptFeignApplication.class, args);}
}
7.浏览器访问
全局降级
针对所有业务方法都配置降级方法,这极有可能会造成代码的急剧膨胀。为了解决该问题,我们还可以为所有业务方法指定一个全局的回退方法
1.注解配置
@Slf4j
@RestController
@DefaultProperties(defaultFallback = "dept_Global_FallbackMethod") //全局的服务降级方法
public class HystrixController_Consumer {
……
}
2.创建方法
创建一个名为 dept_Global_FallbackMethod 的全局回退方法
/*** 全局的 fallback 方法,* 回退方法必须和 hystrix 的执行方法在相同类中* @DefaultProperties(defaultFallback = "dept_Global_FallbackMethod") 类上注解,请求方法上使用 @HystrixCommand 注解*/
public String dept_Global_FallbackMethod() {return "C语言中文网提醒您,运行出错或服务端系统繁忙,请稍后再试!(客户端全局回退方法触发,)";
}
降级(FallBack)方法必须与其对应的业务方法在同一个类中,否则无法生效
3.业务方法标注注解
在所有的业务方法上都标注 @HystrixCommand 注解,将 deptInfo_Timeout() 方法上的 @HystrixCommand(fallbackMethod = "dept_TimeoutHandler") 修改为 @HystrixCommand 即可
//在客户端进行降级
@RequestMapping(value = "/consumer/dept/hystrix/timeout/{id}")
@HystrixCommand
public String deptInfo_Timeout(@PathVariable("id") Integer id) {String s = deptHystrixService.deptInfo_Timeout(id);log.info(s);return s;
}
全局降级方法的优先级较低,只有业务方法没有指定其降级方法时,服务降级时才会触发全局回退方法。若业务方法指定它自己的回退方法,那么在服务降级时,就只会直接触发它自己的回退方法,而非全局回退方法。
4.浏览器访问
服务熔断
简介
熔断机制是应对服务雪崩的一种链路保护机制,当服务出现故障时,服务会进行降级,熔断该服务节点,迅速返回错误响应信息。当检测到服务访问正常时,恢复其链路节点
熔断参数设置
①circuitBreaker.enabled:是否开启熔断;
②circuitBreaker.requestVolumeThreshold:当前服务失败几次后开启断路,默认20次;
③circuitBreaker.sleepWindowInMilliseconds:设置断路时间,过了该时间后会尝试恢复,在断路时间内,即使请求正确也会走降级方法;
熔断类型
在熔断机制中涉及了三种熔断类型:
熔断打开
熔断打开后,在此时间内不会对该服务进行调用,而是直接访问降级方法。通过设置熔断时间,当达到该时间后,会尝试恢复该服务
熔断关闭
熔断关闭代表服务正常,不会干扰正常服务调用。
熔断半开
熔断半开时,请求可以访问服务,若请求正常访问,则熔断会关闭;若请请求不正常,继续熔断,调用降级方法。
熔断机制
熔断机制是通过 Hystrix 实现的。Hystrix 会监控微服务间调用的状况,当失败调用到一定比例时(例如 5 秒内失败 20 次),就会启动熔断机制
使用步骤
1.当服务的调用出错率达到或超过 Hystix 规定的比率(默认为 50%)后,熔断器进入熔断开启状态。
2.熔断器进入熔断开启状态后,Hystrix 会启动一个休眠时间窗,在这个时间窗内,该服务的降级逻辑会临时充当业务主逻辑,而原来的业务主逻辑不可用。
3.当有请求再次调用该服务时,会直接调用降级逻辑快速地返回失败响应,以避免系统雪崩。
4.当休眠时间窗到期后,Hystrix 会进入半熔断转态,允许部分请求对服务原来的主业务逻辑进行调用,并监控其调用成功率。
5.如果调用成功率达到预期,则说明服务已恢复正常,Hystrix 进入熔断关闭状态,服务原来的主业务逻辑恢复;否则 Hystrix 重新进入熔断开启状态,休眠时间窗口重新计时,继续重复第 2 到第 5 步。
示例
1.定义接口
public interface DeptService {// hystrix 熔断器示例 okpublic String deptInfo_Ok(Integer id);//hystrix 熔断器超时案例public String deptInfo_Timeout(Integer id);// Hystrix 熔断机制案例public String deptCircuitBreaker(Integer id);
}
2.实现接口
实现类 DeptServiceImpl 添加 deptCircuitBreaker() 的方法实现及其回退方法
//Hystrix 熔断案例
@Override
@HystrixCommand(fallbackMethod = "deptCircuitBreaker_fallback", commandProperties = {//以下参数在 HystrixCommandProperties 类中有默认配置@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //是否开启熔断器@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "1000"), //统计时间窗@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //统计时间窗内请求次数@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗口期@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //在统计时间窗口期以内,请求失败率达到 60% 时进入熔断状态
})
public String deptCircuitBreaker(Integer id) {if (id < 0) {//当传入的 id 为负数时,抛出异常,调用降级方法throw new RuntimeException("c语言中文网提醒您,id 不能是负数!");}String serialNum = IdUtil.simpleUUID();return Thread.currentThread().getName() + "\t" + "调用成功,流水号为:" + serialNum;
}
//deptCircuitBreaker 的降级方法
public String deptCircuitBreaker_fallback(Integer id) {return "c语言中文网提醒您,id 不能是负数,请稍后重试!\t id:" + id;
}
3.方法对外提供服务
// Hystrix 服务熔断
@RequestMapping(value = "/dept/hystrix/circuit/{id}")
public String deptCircuitBreaker(@PathVariable("id") Integer id){String result = deptService.deptCircuitBreaker(id);log.info("result:"+result);return result;
}
4.浏览器访问
故障监控
Hystrix 还提供了准实时的调用监控功能,Hystrix 会持续地记录所有通过 Hystrix 发起的请求的执行信息,并以统计报表的形式展示给用户,包括每秒执行请求的数量、成功请求的数量和失败请求的数量等
1.添加依赖
<!--hystrix-dashboard 监控的依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency>
2.application.yml 中添加配置
#http://eureka7001.com:9002/hystrix 熔断器监控页面
# localhost:8004//actuator/hystrix.stream 监控地址
hystrix:dashboard:proxy-stream-allow-list:- "localhost"
3.主启动类上添加 @EnableHystrixDashboard 注解,开启 Hystrix 监控功能
@SpringBootApplication
@EnableHystrixDashboard
public class MicroServiceCloudConsumerDeptHystrixDashboard9002Application {public static void main(String[] args) {SpringApplication.run(MicroServiceCloudConsumerDeptHystrixDashboard9002Application.class, args);}
}
4.创建配置类
@Configuration
public class HystrixDashboardConfig {/*** Hystrix dashboard 监控界面必须配置* @return*/@Beanpublic ServletRegistrationBean getServlet() {HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);registrationBean.setLoadOnStartup(1);registrationBean.addUrlMappings("/actuator/hystrix.stream");//访问路径registrationBean.setName("hystrix.stream");return registrationBean;}
}
5.浏览器访问
相关文章:

Spring Cloud之服务熔断与降级(Hystrix)
目录 Hystrix 概念 作用 服务降级 简介 使用场景 接口降级 服务端服务降级 1.添加依赖 2.定义接口 3.实现接口 4.Controller类使用 5.启动类添加注释 6.浏览器访问 客户端服务降级 1.添加依赖 2.application.yml 中添加配置 3.定义接口 4.Controller类使用 …...
HashMap 哈希碰撞、负载因子、插入方式、扩容倍数
HashMap 怎么解决的哈希碰撞问题? 主要采用了链地址法。具体来说: 每个哈希桶不仅存储一个键-值对,而是存储一个链表或树结构。这样,具有相同哈希值的键-值对可以被存储在同一个哈希桶中,并通过链表或树结构来解决碰…...

【Unity3D】Unity与Android交互
1 Unity 发布 apk 1.1 安装 Android Build Support 在 Unity Hub 中打开添加模块窗口,操作如下。 选择 Android Build Support 安装,如下(笔者这里已安装过)。 创建一个 Unity 项目,依次点击【File→Build Settings→…...

信号去噪算法
引言 在实际世界中,我们所获得的信号通常都包含了各种干扰和噪音。这些噪音可能来自电子设备、环境条件或传感器本身,它们会损害信号的质量,降低信息提取的准确性。因此,信号去噪和降噪技术在科学、工程和医学领域中扮演着至关重…...
GPT带我学-设计模式-10观察者模式
1 请你介绍一下观察者模式 观察者模式(Observer Pattern)是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者&…...
JDK - 常用的设计模式
单例模式 : Runtime 类:Java 运行时环境是单例的,可以通过 Runtime.getRuntime() 方法获得实例。Calendar 类:Calendar.getInstance() 方法返回的是一个单例的 Calendar 实例。数据源连接池:连接池的管理通常采用单例模…...
华为OD机考算法题:寻找最大价值的矿堆
题目部分 题目寻找最大价值的矿堆难度难题目说明给你一个由 0(空地)、1(银矿)、2(金矿)组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。 假设银矿价值…...

wf-docker集群搭建(未完结)
系列文章目录 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、redis集群二、mysql集群三、nacos集群1. 环境要求2. 拉取镜像2.1. 拉取镜像方式配置集群2.2. 自定义nacos镜像配置集群 3 自定义…...
uni-app 在 APP 端的版本强制更新与热更新
整包更新与热更新的区别 ① 整包更新是指下载完整 apk 文件进行覆盖安装 ② 热更新是指把 app 有改动的地方打包进 wgt 文件,只更新 wgt 文件中的内容,不进行整包安装,在用户视角也叫做省流量更新 版本号规则约束 建议严格遵循 Semantic …...

实在智能受邀参加第14届珠中江数字化应用大会,AI赋能智能制造,共话“湾区经验”
制造业是实体经济的主体,是技术创新的主战场,是供给侧结构性改革的重要领域。抢占新一轮产业竞争制高点,制造业的数字化转型已成为行业升级的必由之路。 10月21日,第14届“珠中江”(珠海、中山、江门)数字…...
Qt 窗口的尺寸
默认尺寸 对于一个Qt的窗口(继承于QWidget),获取其窗体尺寸的方法size(); 以一个Qt创建Qt Widgets Application项目的默认生成代码为基础,做如下测试 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent…...

游戏数据分析对于运营游戏平台的重要性
游戏数据分析对于运营游戏平台具有至关重要的意义,它可以提供深入的见解,帮助了解玩家行为、偏好和互动,从而优化游戏体验,提高玩家参与度和留存率。 首先,通过游戏数据分析,运营者可以了解玩家在游戏中的表…...

微信群发消息的正确打开方式,让你的社交更高效!
在当今的社交媒体时代,微信已经成为了我们生活中必不可少的一部分。而微信的群发消息功能,让我们可以方便地将信息一次性发送给多个联系人。然而,微信的群发消息功能有一个限制,即每次只能群发200个联系人。这对于需要发送消息给大…...

HTML5语义化标签 header 的详解
🌟🌟🌟 专栏详解 🎉 🎉 🎉 欢迎来到前端开发之旅专栏! 不管你是完全小白,还是有一点经验的开发者,在这里你会了解到最简单易懂的语言,与你分享有关前端技术和…...

SpringCloud复习:(2)@LoadBalanced注解的工作原理
LoadBalanced注解标记了一个RestTemplate或WebClient bean使用LoadBalancerClient来进行负载均衡。 LoadBalancerAutoConfiguration类给带注解的RestTemplate添加了拦截器:LoadBalancerInterceptor. 具体流程如下: 首先定义一个LoadBalancerInterceptor…...
vue钩子函数以及例子
Vue.js 是一个基于组件化的前端框架,它提供了一些钩子函数,用于控制组件在不同阶段的行为和处理。以下是 Vue.js 常用的钩子函数以及它们的作用和示例: beforeCreate:在实例被创建之前调用。此时组件的数据、方法等还没有被初始化…...

redis场用命令及其Java操作
目录 1. Redis入门 1.1 Redis简介 1.2 Redis下载与安装 1.2.1 Redis下载 1.2.2 Redis安装 1.3 Redis服务启动与停止 1.3.1 服务启动命令 1.3.2 客户端连接命令 1.3.3 修改Redis配置文件 1.3.4 Redis客户端图形工具 2. Redis数据类型 2.1 五种常用数据类型介绍 2.2 …...

UG\NX二次开发 同时设置多个对象的高亮状态 UF_DISP_set_highlights
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 感谢粉丝订阅 感谢 captainliubang 订阅本专栏,非常感谢。 简介 UG\NX二次开发 同时设置多个对象的高亮状态 UF_DISP_set_highlights 效果 代码(在for循环中逐个设置多个对象…...
Qt+树莓派4B 手动设置系统日期和时间
文章目录 前言一、设置日期二、设置时间 前言 某些设备需要在无网络环境下工作,系统时间和日期无法通过网络实时同步,此时就需要人为设置. 一、设置日期 QString m_date,m_time;QDateEdit *dateEdit new QDateEdit(this); dateEdit->setFixedSize(250,60); connect(date…...
用大顶堆和小顶堆实现优先队列
大顶堆小顶堆(或大根堆小根堆) 利用大顶堆实现优先队列,所谓大顶堆,容器内部元素是有序的,而且是按从大到小排序的(小顶堆刚好相反,从小到大)。容器只有一个出口一个入口࿰…...

AT_abc409_e [ABC409E] Pair Annihilation
AT_abc409_e [ABC409E] Pair Annihilation 赛时没开longlong挂了。 思路 首先我们可以把这棵树转化为一颗有根树,且所有电子的都朝根节点移动。 那么接下来我们就需要选择一个最优的树根。 考虑换根dp。 但是可以发现换根时答案其实是没有变化的。 我们设 f…...
SQL进阶之旅 Day 21:临时表与内存表应用
【SQL进阶之旅 Day 21】临时表与内存表应用 文章简述 在SQL开发过程中,面对复杂查询、数据预处理和性能优化时,临时表和内存表是不可或缺的工具。本文深入讲解了临时表(Temporary Table)和内存表(Memory Table&#x…...
(新手友好)MySQL学习笔记(6):分组查询,正则表达式
目录 分组查询 创建分组 过滤分组 分组查询练习 正则表达式 匹配单个实例 匹配多个实例 正则表达式练习 练习答案 分组查询练习答案 正则表达式练习答案 分组查询 创建分组 group by 子句:根据一个或多个字段对结果集进行分组,在分组的字段上…...
【从前端到后端导入excel文件实现批量导入-笔记模仿芋道源码的《系统管理-用户管理-导入-批量导入》】
批量导入预约数据-笔记 前端场馆列表后端 前端 场馆列表 该列表进入出现的是这样的,这儿是列表操作 <el-table-column label"操作" align"center" width"220px"><template #default"scope"><el-buttonlinktype"…...

基于dify的营养分析工作流:3分钟生成个人营养分析报告
你去医院做体检,需要多久拿到体检报告呢?医院会为每位病人做一份多维度的健康报告吗?"人工报告需1小时/份?数据误差率高达35%?传统工具无法个性化? Dify工作流AI模型的组合拳,正在重塑健康…...

c++对halcon的动态链接库dll封装及调用(细细讲)
七个部分(是个大工程) 一,halcon封装函数导出cpp的内容介绍 二,c++中对halcon环境的配置 三,在配置环境下验证halcon代码 四,dll项目创建+环境配置 五,编辑dll及导出 六,调用打包好的动态链接库的配置 七,进行测试 一,halcon的封装及导出cpp的介绍 1,我这里…...

【优选算法】分治
一:颜色分类 class Solution { public:void sortColors(vector<int>& nums) {// 三指针法int n nums.size();int left -1, right n, i 0;while(i < right){if(nums[i] 0) swap(nums[left], nums[i]);else if(nums[i] 2) swap(nums[--right], num…...
qt network 整体框架
以下是 Qt 网络模块中 QNetworkInterface、TCP、UDP 及相关类的层次关系图及说明: 一、Qt 网络模块层次结构 ┌─────────────────────────────────────────────────────────────┐ │ QtNetwork 模…...
html如何在一张图片上的某一个区域做到点击事件
在HTML中,可以通过<map>和<area>标签来实现对图片的某个区域添加点击事件。这种方法通常用于创建图像地图(Image Map),允许用户点击图片的不同区域触发不同的事件。 以下是实现步骤和代码示例: 1. 准备图…...

CAN通信收发测试(USB2CAN模块测试实验)
1.搭建测试环境 电脑:安装 USB 驱动,安装原厂调试工具,安装cangaroo(参考安装包的入门教程即可) USB驱动路径:~\CAN分析仪资料20230701_Linux\硬件驱动程序 原厂调试工具路径:~\CAN分析仪资料2…...