当前位置: 首页 > news >正文

解救应用启动危机:Spring Boot的FailureAnalyzer机制

目录

一、走进FailureAnalyzer

二、在Spring Boot中如何生效

三、为什么可能需要自定义FailureAnalyzer

四、实现自定义基本步骤

(一)完整步骤要求

(二)注册方式说明

通过Spring Boot的spring.factories文件(建议方式)

在启动类中手动注册(本人不建议)

五、实现自定义举例

六、一些建议


一、走进FailureAnalyzer

想象一下,你正在开发一个基于Spring Boot的网络应用程序,你已经编写了一大堆代码,做了各种配置,终于迫不及待地想要启动你的应用程序,看看它是不是如你所愿地运行。

你兴奋地运行了启动命令,但突然间,控制台上出现了一堆红色的错误信息。如下:

可以立刻看到这个报错来自于LoggingFailureAnalysisReporter,其内部其实就是Spring Boot中被誉为故障排查神器的工具FailureAnalyzer。你决定让它出马,看看能否解决你的问题。

你应该感到非常惊讶和兴奋,因为FailureAnalyzer不仅仅找出了问题,还给出了解决方案:按照建议修复了配置,再次启动应用程序,这一次一切都运行得非常顺利。

通过这个简单的场景,你立刻感受到了FailureAnalyzer的价值和魔力。它就像是你的应用程序启动的保险,让你在遇到问题时能够迅速找出解决方案,让你的开发过程更加流畅和高效。

二、在Spring Boot中如何生效

在Spring Boot的spring.factories文件(位于META-INF目录下)中已经包含了一些FailureAnalyzer的配置,FailureAnalyzer实现类通常在spring.factories文件中被声明,以便在应用程序启动时被Spring Boot自动发现并注册。

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.jdbc.DataSourceFailedAnalyzer,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisJmsConnectionFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.hornetq.HornetQConnectFailureAnalyzer,\
org.springframework.boot.autoconfigure.jms.hornetq.HornetQDependencyExceptionAnalyzer,\
org.springframework.boot.autoconfigure.solr.SolrExceptionAnalyzer,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBeanNotAvailableAnalyzer,\
org.springframework.boot.cloud.CloudPlatformConnectorsFailureAnalyzer,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessorFailureAnalyzer,\
org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessorChecker,\
org.springframework.boot.devtools.autoconfigure.DevToolsMissingFilterFailureAnalyzer,\
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration$LocalDevToolsFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideAnalyzer,\
org.springframework.boot.diagnostics.analyzer.IllegalComponentScanFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidEmbeddedServletContainerConfigurationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidTemplateAvailabilityProviderAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NonCompatibleConfigurationClassFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.SingleConstructorInjectionAnalyzer

当应用程序启动失败时,Spring Boot会自动触发这个机制,尝试识别和处理启动失败的原因,并提供有用的诊断信息和解决方案。

三、为什么可能需要自定义FailureAnalyzer

当然,如果有需要的话,我们可以自定义FailureAnalyzer来更灵活地处理应用程序启动失败的情况,提供更精准的故障诊断和解决方案等,特别是针对做基础架构的同学。

理由说明
特定错误情况处理

默认的FailureAnalyzer无法准确识别或处理特定的错误情况。通过自定义可以针对这些特定的错误情况编写定制化的诊断逻辑,提供更精准的故障诊断和解决方案。

额外的诊断信息

默认的FailureAnalyzer只提供基本的诊断信息,但在某些情况下,可能需要更多的详细信息来准确诊断问题。通过自定义可添加额外的诊断逻辑,收集更多有用的信息来更好地理解问题。

集成外部系统应用程序与外部系统集成,而启动失败可能是由于与这些外部系统的交互出现问题所致。通过自定义可以集成额外的逻辑,例如调用外部API或检查外部系统的状态,以诊断和解决与外部系统相关的问题。
定制化的解决方案某些错误情况需要特定的解决方案,通过自定义可以根据应用程序的特定需求或约束,提供定制化的解决方案,以更好地满足应用程序的需求。

四、实现自定义基本步骤

(一)完整步骤要求

要实现自定义的FailureAnalyzer,我们需要完成以下步骤:

  1. 自定义异常,并创建检查要求规定。
  2. 创建一个类并实现AbstractFailureAnalyzer接口,重写analyze()方法,用于分析异常并返回FailureAnalysis对象。
  3. 将自定义的FailureAnalyzer类注册到Spring Boot应用程序中。

注意在 Spring Boot 应用程序中,自定义的多个失败分析器在实现上没有固定的先后次序。当应用程序启动时,Spring Boot 会自动扫描并注册所有的失败分析器,然后按照它们的类名顺序进行调用。这意味着,无论你如何组织和编写你的失败分析器类,它们都将在应用程序启动时同时注册,并且没有先后次序。

(二)注册方式说明

要让自定义的FailureAnalyzer生效注册到Spring Boot应用程序中,一般有两种方法:

通过Spring Boot的spring.factories文件(建议方式)

  1. src/main/resources目录下创建一个名为META-INF/spring.factories的文件(如果已存在则跳过此步骤)。
  2. spring.factories文件中添加用于实现的自定义FailureAnalyzer类,和上文中展示的spring.factories文件中的格式一样。

在启动类中手动注册(本人不建议)

在Spring Boot应用程序的启动类(@SpringBootApplication)中手动注册FailureAnalyzer

    public static void main(String[] args) {SpringApplication application = new SpringApplication(ZYFApplication.class);application.addListeners(new ConfigFileFailureAnalyzer());application.run(args);}

后续列举一些案例,但是情况请依据实际项目需求来定。我一般是以上面建议方式进行写的注册。

五、实现自定义举例

假设我们的应用程序在启动时需要加载某些特定的配置文件,但如果对应配置文件不存在将导致应用程序启动失败。默认的FailureAnalyzer可能无法准确地识别或处理这种特定情况,因此我们可以自定义一个FailureAnalyzer来处理这种特定的错误情况。

首先定义必要文件未找到异常如下:

package org.zyf.javabasic.spring.failureanalyzer.exception;/*** @program: zyfboot-javabasic* @description: ConfigFileNotFoundException* @author: zhangyanfeng* @create: 2024-05-02 17:25**/
public class ConfigFileNotFoundException extends RuntimeException {private final String fileNames;public ConfigFileNotFoundException(String fileNames) {super("Configuration file '" + fileNames + "' not found");this.fileNames = fileNames;}public String getFileNames() {return fileNames;}
}

接着创建检查类对我们系统要求的必要文件作出基本的检查并返回要求文件异常基本信息:

package org.zyf.javabasic.spring.failureanalyzer.checker;import com.google.common.collect.Lists;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileNotFoundException;import javax.annotation.PostConstruct;
import java.util.List;/*** @program: zyfboot-javabasic* @description: 系统必要配置文件检查* @author: zhangyanfeng* @create: 2024-05-02 18:14**/
@Component
public class ConfigFileNotFoundChecker {private final ResourceLoader resourceLoader;public ConfigFileNotFoundChecker(ResourceLoader resourceLoader) {this.resourceLoader = resourceLoader;}public boolean exists(String fileName) {Resource resource = resourceLoader.getResource("classpath:" + fileName);return resource.exists();}@PostConstructpublic void checkConfigFiles() throws ConfigFileNotFoundException {// 要检查的文件列表List<String> filesToCheck = Lists.newArrayList();filesToCheck.add("application.yml");filesToCheck.add("zyf_application_context.xml");filesToCheck.add("report-config.xml");filesToCheck.add("urlzyf.properties");// 存储不存在的文件名List<String> notFoundFiles = Lists.newArrayList();// 检查每个文件是否存在for (String fileName : filesToCheck) {if (!exists(fileName)) {notFoundFiles.add(fileName);}}// 如果存在未找到的文件,则抛出异常if (!notFoundFiles.isEmpty()) {throw new ConfigFileNotFoundException(notFoundFiles.toString());}}
}

接着创建并实现AbstractFailureAnalyzer,重写analyze()方法如下:

package org.zyf.javabasic.spring.failureanalyzer.analyzer;import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileNotFoundException;
import org.zyf.javabasic.spring.failureanalyzer.exception.RequiredPropertyException;/*** @program: zyfboot-javabasic* @description: 检查必要文件是否存在异常* @author: zhangyanfeng* @create: 2024-05-02 18:26**/
public class ZYFConfigFileFailureAnalyzer extends AbstractFailureAnalyzer<ConfigFileNotFoundException> {@Overrideprotected FailureAnalysis analyze(Throwable rootFailure, ConfigFileNotFoundException cause) {String description = description(cause);String action = action(cause);return new FailureAnalysis(description, action, cause);}private String description(ConfigFileNotFoundException ex) {return String.format("Failed to load configuration file '%s'.", ex.getFileNames());}private String action(ConfigFileNotFoundException ex) {return String.format("Check if the configuration file:'%s' exists.", ex.getFileNames());}
}

spring.factories中增加本次新增验证:

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFailureAnalyzer

现在其中本地未创建ourlzyf.properties文件,故程序启动报错如下:

符合我们的预期。

接着如果要求针对报告配置文件 report-config.xml 中必须包含数据库连接信息和报告生成器的情况,并要求有更加详细和严格的配置文件格式验证,接着我们继续定义一个异常类且需要指明异常情况。

先定义一个这种类型返回的基本配置错误信息如下:

package org.zyf.javabasic.spring.failureanalyzer.model;/*** @program: zyfboot-javabasic* @description: 表示不同的错误类型,例如缺少必要属性、属性值格式错误等* @author: zhangyanfeng* @create: 2024-05-02 19:57**/
public class ConfigFileFormatErrorInfo {private final boolean fileNotFound;private final ErrorType errorType;private final String fileName;public ConfigFileFormatErrorInfo(boolean fileNotFound, ErrorType errorType, String fileName) {this.fileNotFound = fileNotFound;this.errorType = errorType;this.fileName = fileName;}public boolean isFileNotFound() {return fileNotFound;}public ErrorType getErrorType() {return errorType;}public String getFileName() {return fileName;}public DescriptionAndAction getDescriptionAndAction() {String description;String action;if (fileNotFound) {description = "Configuration file '" + fileName + "' not found";action = "Check if the configuration file exists.";} else {switch (errorType) {case MISSING_PROPERTY:description = "Missing required property in configuration file '" + fileName + "'";action = "Ensure all required properties are provided in the configuration file.";break;case INVALID_VALUE:description = "Invalid value for property in configuration file '" + fileName + "'";action = "Correct the value of the property in the configuration file.";break;case OTHER:default:description = "Other configuration file format error in file '" + fileName + "'";action = "Review the configuration file for formatting issues.";break;}}return new DescriptionAndAction(description, action);}public enum ErrorType {MISSING_PROPERTY,INVALID_VALUE,OTHER}
}package org.zyf.javabasic.spring.failureanalyzer.model;/*** @program: zyfboot-javabasic* @description: DescriptionAndAction* @author: zhangyanfeng* @create: 2024-05-02 20:19**/
public class DescriptionAndAction {private final String description;private final String action;public DescriptionAndAction(String description, String action) {this.description = description;this.action = action;}public String getDescription() {return description;}public String getAction() {return action;}
}

然后定义基本的异常信息如下:

package org.zyf.javabasic.spring.failureanalyzer.exception;import com.alibaba.fastjson.JSON;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;/*** @program: zyfboot-javabasic* @description: 配置文件格式问题异常* @author: zhangyanfeng* @create: 2024-05-02 19:23**/
public class ConfigFileFormatException extends RuntimeException {private final ConfigFileFormatErrorInfo errorInfo;public ConfigFileFormatException(ConfigFileFormatErrorInfo errorInfo) {super("Configuration file format error: " + JSON.toJSONString(errorInfo));this.errorInfo = errorInfo;}public ConfigFileFormatErrorInfo getErrorInfo() {return errorInfo;}}

检查指定的配置文件(report-config.xml)是否符合预期的格式要求:

  1. 必须包含一个名为 "dataSource" 的 Bean 定义,用于配置数据库连接信息。
  2. "dataSource" Bean 中必须包含以下属性:driverClassName:数据库驱动类名;url:数据库连接 URL;username:数据库用户名;password:数据库密码。
  3. password 属性必须已加密,即以特定字符串开头。
  4. 必须包含一个名为 "reportGenerator" 的 Bean 定义,用于配置报告生成器。
  5. "reportGenerator" Bean 中必须包含一个名为 dataSource 的属性引用,指向之前定义的 "dataSource" Bean。

如果配置文件不符合上述要求之一,就会抛出相应的异常,指示配置文件格式错误。具体对应的检查实现如下:

package org.zyf.javabasic.spring.failureanalyzer.checker;import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileFormatException;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;import javax.annotation.PostConstruct;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;import static org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo.ErrorType.*;/*** @program: zyfboot-javabasic* @description: 指定配置文件验证逻辑* @author: zhangyanfeng* @create: 2024-05-02 20:12**/
@Component
public class ConfigFileFormatChecker {@Autowiredprivate ResourceLoader resourceLoader;@PostConstructpublic void checkConfigFileFormat() {String fileName = "report-config.xml";Resource resource = resourceLoader.getResource("classpath:" + fileName);if (!resource.exists()) {throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(true, null, fileName));}Element root = null;try (InputStream inputStream = resource.getInputStream()) {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(new InputSource(inputStream));// 获取根元素root = document.getDocumentElement();} catch (Exception e) {throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(true, OTHER, fileName));}// 检查 dataSource Bean 定义checkDataSourceDefinition(root, fileName);// 检查报告生成器定义checkReportGeneratorDefinition(root, fileName);}private void checkDataSourceDefinition(Element root, String fileName) {// 获取 dataSource 元素NodeList dataSourceList = root.getElementsByTagName("bean");for (int i = 0; i < dataSourceList.getLength(); i++) {Element dataSourceElement = (Element) dataSourceList.item(i);String id = dataSourceElement.getAttribute("id");if ("dataSource".equals(id)) {// 获取 driverClassName 属性String driverClassName = dataSourceElement.getElementsByTagName("property").item(0).getAttributes().getNamedItem("value").getNodeValue();// 获取 url 属性String url = dataSourceElement.getElementsByTagName("property").item(1).getAttributes().getNamedItem("value").getNodeValue();// 获取 username 属性String username = dataSourceElement.getElementsByTagName("property").item(2).getAttributes().getNamedItem("value").getNodeValue();// 获取 password 属性String password = dataSourceElement.getElementsByTagName("property").item(3).getAttributes().getNamedItem("value").getNodeValue();if (StringUtils.isAnyBlank(driverClassName, url, username, password)) {throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, MISSING_PROPERTY, fileName));}if (!isPasswordEncrypted(password)) {throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, INVALID_VALUE, fileName));}}}}private void checkReportGeneratorDefinition(Element root, String fileName) {// 获取 reportGenerator 元素NodeList reportGeneratorList = root.getElementsByTagName("bean");for (int i = 0; i < reportGeneratorList.getLength(); i++) {Element reportGeneratorElement = (Element) reportGeneratorList.item(i);String id = reportGeneratorElement.getAttribute("id");if ("reportGenerator".equals(id)) {// 获取 dataSource 属性的引用String dataSourceRef = reportGeneratorElement.getElementsByTagName("property").item(0).getAttributes().getNamedItem("ref").getNodeValue();if (StringUtils.isAnyBlank(dataSourceRef)) {throw new ConfigFileFormatException(new ConfigFileFormatErrorInfo(false, MISSING_PROPERTY, fileName));}}}}private boolean isPasswordEncrypted(String password) {// 检查密码是否已加密,这里可以根据具体加密方式进行验证return password.startsWith("Zyf");}
}

接着创建并实现AbstractFailureAnalyzer,重写analyze()方法如下:

package org.zyf.javabasic.spring.failureanalyzer.analyzer;import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.zyf.javabasic.spring.failureanalyzer.exception.ConfigFileFormatException;
import org.zyf.javabasic.spring.failureanalyzer.model.ConfigFileFormatErrorInfo;
import org.zyf.javabasic.spring.failureanalyzer.model.DescriptionAndAction;/*** @program: zyfboot-javabasic* @description: 指定配置文件具体格式要求* @author: zhangyanfeng* @create: 2024-05-02 20:31**/
public class ZYFConfigFileFormatFailureanalyzer extends AbstractFailureAnalyzer<ConfigFileFormatException> {@Overrideprotected FailureAnalysis analyze(Throwable rootFailure, ConfigFileFormatException cause) {ConfigFileFormatErrorInfo errorInfo = cause.getErrorInfo();String description;String action;if (errorInfo.isFileNotFound()) {description = "Configuration file '" + errorInfo.getFileName() + "' not found";action = "Check if the configuration file exists.";} else {DescriptionAndAction descriptionAndAction = errorInfo.getDescriptionAndAction();description = descriptionAndAction.getDescription();action = descriptionAndAction.getAction();}return new FailureAnalysis(description, action, cause);}
}

spring.factories中增加本次新增验证:

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFailureAnalyzer,\
org.zyf.javabasic.spring.failureanalyzer.analyzer.ZYFConfigFileFormatFailureanalyzer

但是我实际report-config.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 数据库连接信息 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/zyf"/><property name="username" value="root"/><property name="password" value="Zsyf2014"/></bean><!-- 报告生成器 --><bean id="reportGenerator" class="org.zyf.javabasic.spring.beanFactory.ReportGenerator"><property name="dataSource" ref="dataSource"/><!-- 其他配置属性 --></bean>
</beans>

由于数据库加密不正确,故程序启动报错如下:

六、一些建议

如果确定了需要创建自定义的 FailureAnalyzer 时,必须有几个注意事项:

  • 确保 FailureAnalyzer 能够准确地识别失败的原因,避免误导性的诊断,帮助更快地找到并解决问题。
  • 在诊断中提供尽可能详细的信息,包括失败的具体原因、发生失败的位置等。
  • 提供清晰的建议或解决方案,可以包括修复代码、调整配置或执行其他操作的建议。

相关源码依旧在常用的github地址中。

相关文章:

解救应用启动危机:Spring Boot的FailureAnalyzer机制

目录 一、走进FailureAnalyzer 二、在Spring Boot中如何生效 三、为什么可能需要自定义FailureAnalyzer 四、实现自定义基本步骤 &#xff08;一&#xff09;完整步骤要求 &#xff08;二&#xff09;注册方式说明 通过Spring Boot的spring.factories文件&#xff08;建…...

win11个性化锁屏界面怎么关闭?

win11个性化锁屏界面关闭方法对于win11用户来说&#xff0c;关闭个性化锁屏界面是一个常见问题。本文将由php小编苹果详细介绍如何执行此操作&#xff0c;分步指导并提供操作截图。继续阅读以了解具体步骤。 win11个性化锁屏界面关闭方法 第一步&#xff0c;点击底部Windows图…...

白酒:白酒香型与品质消费的关系及影响

云仓酒庄的豪迈白酒作为中国白酒的品牌&#xff0c;其白酒香型与品质消费的关系及影响备受关注。随着消费者对品质的重视程度不断提高&#xff0c;了解白酒香型与品质之间的关系对于云仓酒庄和消费者都具有重要意义。 经云仓酒庄豪迈白酒分析&#xff0c;白酒香型与品质消费的关…...

智能BI(后端)-- 系统优化(安全性,数据存储,限流)

文章目录 安全性todo 数据存储限流限流的几种算法限流粒度限流的实现本地限流&#xff08;单机限流&#xff09;Redisson实现分布式限流(多机限流) 安全性 问题引入&#xff1a;如果用户上传一个超大的文件怎么办&#xff1f;比如1000G&#xff1f; 预防&#xff1a; 只要涉及…...

探索数字社交的奇迹:解读Facebook的革命性影响

1. 社交互动的全新模式 Facebook的出现不仅仅是一个社交媒体平台的诞生&#xff0c;更是一种全新的社交互动模式的开启。传统的社交模式主要依赖于面对面的交流&#xff0c;而Facebook则将社交推向了全新的数字化平台&#xff0c;使得人们可以在虚拟的世界里建立和维系社交关系…...

FileCodeBox-Lite:轻量级文件分享解决方案

在数字时代&#xff0c;文件分享是一个常见的需求&#xff0c;无论是个人用户还是企业团队。FileCodeBox-Lite提供了一个简单、高效且安全的文件分享解决方案。以下是对FileCodeBox-Lite项目的详细介绍。 项目简介 FileCodeBox-Lite是一个轻量级的文件分享系统&#xff0c;…...

【ARM】ARM寄存器和异常处理

目录 1.指令的执行过程 2. ARM处理器概述 3.ARM指令集 4.ARM存储模型 5. ARM工作模式 6.ARM寄存器组织 &#xff08;1&#xff09;寄存器 &#xff08;2&#xff09; ARM寄存器 &#xff08;3&#xff09;CPSR寄存器​​​​​​​ 7. ARM异常处理 &#xff08;1&am…...

数仓建模【埋点设计与管理】

埋点设计与管理 埋点的作用 分析用户转化以及留存&#xff1a;分析用户偏好收集市场反馈保障用户数据安全定位异常其他作用 埋点数仓设计 数据进入数仓之前我们就需要设计好数仓表&#xff0c;埋点表的数据有几个特点&#xff1a; 数据量非常大&#xff0c;可能是所有数据集…...

Spring Clound介绍

Spring Cloud 是一系列框架的集合&#xff0c;它利用 Spring Boot 的开发便利性简化了分布式系统&#xff08;例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话和集群状态&#xff09;的开发。Spring Cloud 旨在为开发者…...

Redhat Linux忘记密码解决方案

1、重启系统 2、将光标移动到要启动的内核 3、按e编辑当前条目 4、将光标移动以Linux开头的行&#xff0c;此为内核命令行 5、在末尾添加人的rd.break 6、按ctrlx继续启动&#xff0c;如果发现输入的rd.break不能进入到伪系统&#xff0c;那么改为 rd.break consoletty0 (按ctr…...

对于子数组问题的动态规划

前言 先讲讲我对于这个问题的理解吧 当谈到解决子数组问题时&#xff0c;动态规划(DP)是一个强大的工具&#xff0c;它在处理各种算法挑战时发挥着重要作用。动态规划是一种思想&#xff0c;它通过将问题分解成更小的子问题并以一种递归的方式解决它们&#xff0c;然后利用这些…...

Instal IIS on Windows Server 2022 Datacenter

和以往版本一样&#xff0c;没有什么不同&#xff0c;So easy&#xff01; WinR - ServerManager.exe 打开服务器管理器&#xff0c;点击【添加角色和功能】&#xff0c;选择自己想要的角色和功能。 一、开始之前&#xff1a;帮助说明&#xff0c;点击【下一步】&#xff1b;…...

飞天使-k8s知识点30-kubernetes安装1.28.0版本-使用containerd方式

文章目录 安装前准备containerd 配置内核参数优化安装nerdctl以上是所有机器全部安装开始安装初始化&#xff0c;这步骤容易出问题&#xff01; 安装前准备 内核升级包的md5,本人已验证&#xff0c;只要是这个md5值&#xff0c;放心升级 1ea91ea41eedb35c5da12fe7030f4347 ke…...

Oracle 误操作insert delete update 数据回滚

查询回滚数据 select * from tablename AS OF TIMESTAMP TO_TIMESTAMP(2023-12-29 10:29:00,yyyy-mm-dd hh24:mi:ss) where not exists (select 1 from tablename A where A.xh tablename.xh and A.TIME tablename.TIME); TO_TIMESTAMP(2023-12-29 10:29:00,yyyy-mm-dd h…...

Linux系统(CentOS)下安装配置 Nginx 超详细图文教程

一、下载并安装 1.打开nginx官网并点击右侧的download&#xff0c;Nginx官网下载地址 2.选择稳定版本 我放在/usr/local/nginx/下&#xff0c;新建文件夹 mkdir /usr/local/nginx/ 通过xftp传输到Linux的服务器上&#xff0c;这里方法不过多复述。 或者如果Linux联网&#xf…...

追求完美用户体验,从变量名设计的细节抓起

在一个安静的办公室里&#xff0c;卧龙和凤雏正坐在电脑前忙碌地工作着。阳光透过窗户洒在他们的脸上&#xff0c;映照出专注的神情。 “变量命名让人摸不着头脑&#xff0c;光看变量名很难搞清楚它的用途。”卧龙眉头紧皱&#xff0c;表情严肃地说道。 “哦&#xff1f;具体是…...

matlab实现K均值聚类

在MATLAB中实现聚类分析&#xff0c;可以使用MATLAB内置的聚类函数&#xff0c;如kmeans&#xff08;用于K均值聚类&#xff09;&#xff0c;linkage和cluster&#xff08;用于层次聚类&#xff09;&#xff0c;或者使用MATLAB的统计和机器学习工具箱中的其他函数。 以下是一个…...

详解BOM编程

华子目录 BOM编程window对象常见的window对象的属性常见的window对象的方法注意 history对象history对象的属性history对象的方法 screen 对象navigator 对象属性方法 location对象属性方法示例 BOM编程 JavaScript本质是在浏览器中运行&#xff0c;所以JavaScript提供了BOM&a…...

情感分类学习笔记(1)

文本情感分类&#xff08;二&#xff09;&#xff1a;深度学习模型 - 科学空间|Scientific Spaces 一、代码理解 cw lambda x: list(jieba.cut(x)) #定义分词函数 您给出的代码定义了一个使用 jieba 分词库的分词函数。jieba 是一个用于中文分词的 Python 库。该函数 cw 是…...

EtherCAT运动控制器Delta机械手应用

ZMC406硬件介绍 ZMC406是正运动推出的一款多轴高性能EtherCAT总线运动控制器&#xff0c;具有EtherCAT、EtherNET、RS232、CAN和U盘等通讯接口&#xff0c;ZMC系列运动控制器可应用于各种需要脱机或联机运行的场合。 ZMC406支持6轴运动控制&#xff0c;最多可扩展至32轴&#…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...