解救应用启动危机: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来更灵活地处理应用程序启动失败的情况,提供更精准的故障诊断和解决方案等,特别是针对做基础架构的同学。
| 理由 | 说明 |
|---|---|
| 特定错误情况处理 | 默认的 |
| 额外的诊断信息 | 默认的 |
| 集成外部系统 | 应用程序与外部系统集成,而启动失败可能是由于与这些外部系统的交互出现问题所致。通过自定义可以集成额外的逻辑,例如调用外部API或检查外部系统的状态,以诊断和解决与外部系统相关的问题。 |
| 定制化的解决方案 | 某些错误情况需要特定的解决方案,通过自定义可以根据应用程序的特定需求或约束,提供定制化的解决方案,以更好地满足应用程序的需求。 |
四、实现自定义基本步骤
(一)完整步骤要求
要实现自定义的FailureAnalyzer,我们需要完成以下步骤:
- 自定义异常,并创建检查要求规定。
- 创建一个类并实现AbstractFailureAnalyzer接口,重写analyze()方法,用于分析异常并返回FailureAnalysis对象。
- 将自定义的FailureAnalyzer类注册到Spring Boot应用程序中。
注意在 Spring Boot 应用程序中,自定义的多个失败分析器在实现上没有固定的先后次序。当应用程序启动时,Spring Boot 会自动扫描并注册所有的失败分析器,然后按照它们的类名顺序进行调用。这意味着,无论你如何组织和编写你的失败分析器类,它们都将在应用程序启动时同时注册,并且没有先后次序。
(二)注册方式说明
要让自定义的FailureAnalyzer生效注册到Spring Boot应用程序中,一般有两种方法:
通过Spring Boot的spring.factories文件(建议方式)
- 在
src/main/resources目录下创建一个名为META-INF/spring.factories的文件(如果已存在则跳过此步骤)。 - 在
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)是否符合预期的格式要求:
- 必须包含一个名为 "dataSource" 的 Bean 定义,用于配置数据库连接信息。
- "dataSource" Bean 中必须包含以下属性:
driverClassName:数据库驱动类名;url:数据库连接 URL;username:数据库用户名;password:数据库密码。 password属性必须已加密,即以特定字符串开头。- 必须包含一个名为 "reportGenerator" 的 Bean 定义,用于配置报告生成器。
- "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 四、实现自定义基本步骤 (一)完整步骤要求 (二)注册方式说明 通过Spring Boot的spring.factories文件(建…...
win11个性化锁屏界面怎么关闭?
win11个性化锁屏界面关闭方法对于win11用户来说,关闭个性化锁屏界面是一个常见问题。本文将由php小编苹果详细介绍如何执行此操作,分步指导并提供操作截图。继续阅读以了解具体步骤。 win11个性化锁屏界面关闭方法 第一步,点击底部Windows图…...
白酒:白酒香型与品质消费的关系及影响
云仓酒庄的豪迈白酒作为中国白酒的品牌,其白酒香型与品质消费的关系及影响备受关注。随着消费者对品质的重视程度不断提高,了解白酒香型与品质之间的关系对于云仓酒庄和消费者都具有重要意义。 经云仓酒庄豪迈白酒分析,白酒香型与品质消费的关…...
智能BI(后端)-- 系统优化(安全性,数据存储,限流)
文章目录 安全性todo 数据存储限流限流的几种算法限流粒度限流的实现本地限流(单机限流)Redisson实现分布式限流(多机限流) 安全性 问题引入:如果用户上传一个超大的文件怎么办?比如1000G? 预防: 只要涉及…...
探索数字社交的奇迹:解读Facebook的革命性影响
1. 社交互动的全新模式 Facebook的出现不仅仅是一个社交媒体平台的诞生,更是一种全新的社交互动模式的开启。传统的社交模式主要依赖于面对面的交流,而Facebook则将社交推向了全新的数字化平台,使得人们可以在虚拟的世界里建立和维系社交关系…...
FileCodeBox-Lite:轻量级文件分享解决方案
在数字时代,文件分享是一个常见的需求,无论是个人用户还是企业团队。FileCodeBox-Lite提供了一个简单、高效且安全的文件分享解决方案。以下是对FileCodeBox-Lite项目的详细介绍。 项目简介 FileCodeBox-Lite是一个轻量级的文件分享系统,…...
【ARM】ARM寄存器和异常处理
目录 1.指令的执行过程 2. ARM处理器概述 3.ARM指令集 4.ARM存储模型 5. ARM工作模式 6.ARM寄存器组织 (1)寄存器 (2) ARM寄存器 (3)CPSR寄存器 7. ARM异常处理 (1&am…...
数仓建模【埋点设计与管理】
埋点设计与管理 埋点的作用 分析用户转化以及留存:分析用户偏好收集市场反馈保障用户数据安全定位异常其他作用 埋点数仓设计 数据进入数仓之前我们就需要设计好数仓表,埋点表的数据有几个特点: 数据量非常大,可能是所有数据集…...
Spring Clound介绍
Spring Cloud 是一系列框架的集合,它利用 Spring Boot 的开发便利性简化了分布式系统(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话和集群状态)的开发。Spring Cloud 旨在为开发者…...
Redhat Linux忘记密码解决方案
1、重启系统 2、将光标移动到要启动的内核 3、按e编辑当前条目 4、将光标移动以Linux开头的行,此为内核命令行 5、在末尾添加人的rd.break 6、按ctrlx继续启动,如果发现输入的rd.break不能进入到伪系统,那么改为 rd.break consoletty0 (按ctr…...
对于子数组问题的动态规划
前言 先讲讲我对于这个问题的理解吧 当谈到解决子数组问题时,动态规划(DP)是一个强大的工具,它在处理各种算法挑战时发挥着重要作用。动态规划是一种思想,它通过将问题分解成更小的子问题并以一种递归的方式解决它们,然后利用这些…...
Instal IIS on Windows Server 2022 Datacenter
和以往版本一样,没有什么不同,So easy! WinR - ServerManager.exe 打开服务器管理器,点击【添加角色和功能】,选择自己想要的角色和功能。 一、开始之前:帮助说明,点击【下一步】;…...
飞天使-k8s知识点30-kubernetes安装1.28.0版本-使用containerd方式
文章目录 安装前准备containerd 配置内核参数优化安装nerdctl以上是所有机器全部安装开始安装初始化,这步骤容易出问题! 安装前准备 内核升级包的md5,本人已验证,只要是这个md5值,放心升级 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,Nginx官网下载地址 2.选择稳定版本 我放在/usr/local/nginx/下,新建文件夹 mkdir /usr/local/nginx/ 通过xftp传输到Linux的服务器上,这里方法不过多复述。 或者如果Linux联网…...
追求完美用户体验,从变量名设计的细节抓起
在一个安静的办公室里,卧龙和凤雏正坐在电脑前忙碌地工作着。阳光透过窗户洒在他们的脸上,映照出专注的神情。 “变量命名让人摸不着头脑,光看变量名很难搞清楚它的用途。”卧龙眉头紧皱,表情严肃地说道。 “哦?具体是…...
matlab实现K均值聚类
在MATLAB中实现聚类分析,可以使用MATLAB内置的聚类函数,如kmeans(用于K均值聚类),linkage和cluster(用于层次聚类),或者使用MATLAB的统计和机器学习工具箱中的其他函数。 以下是一个…...
详解BOM编程
华子目录 BOM编程window对象常见的window对象的属性常见的window对象的方法注意 history对象history对象的属性history对象的方法 screen 对象navigator 对象属性方法 location对象属性方法示例 BOM编程 JavaScript本质是在浏览器中运行,所以JavaScript提供了BOM&a…...
情感分类学习笔记(1)
文本情感分类(二):深度学习模型 - 科学空间|Scientific Spaces 一、代码理解 cw lambda x: list(jieba.cut(x)) #定义分词函数 您给出的代码定义了一个使用 jieba 分词库的分词函数。jieba 是一个用于中文分词的 Python 库。该函数 cw 是…...
EtherCAT运动控制器Delta机械手应用
ZMC406硬件介绍 ZMC406是正运动推出的一款多轴高性能EtherCAT总线运动控制器,具有EtherCAT、EtherNET、RS232、CAN和U盘等通讯接口,ZMC系列运动控制器可应用于各种需要脱机或联机运行的场合。 ZMC406支持6轴运动控制,最多可扩展至32轴&#…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
