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

SpringBoot优雅关机,监听关机事件,docker配置

Spring Boot 提供了多种方法来实现优雅停机(Graceful Shutdown),这意味着在关闭应用程序之前,它会等待当前正在处理的请求完成,并且不再接受新的请求。

一、优雅停机的基本概念

优雅停机的主要步骤如下:

  1. 停止接收新的请求:一旦收到关闭指令,服务器会停止接受新的请求。
  2. 处理当前请求:系统会继续处理已经在处理中的请求,确保这些请求能够正常完成。
  3. 释放资源:在所有请求处理完毕后,系统会释放已分配的资源,比如关闭数据库连接、断开网络连接等。
  4. 关闭服务:当所有资源都被正确释放之后,系统会安全地关闭服务。

二、实现优雅停机的方法

2.1、在 Spring Boot 2.3 及以上版本中启用优雅停机

从 Spring Boot 2.3 开始,默认集成了对优雅停机的支持,你只需要通过配置文件进行简单的设置即可。

application.ymlapplication.properties 文件中添加以下配置:

server:shutdown: graceful
spring:lifecycle:timeout-per-shutdown-phase: 60s # 设置最大等待时间为60秒

上述配置告诉 Spring Boot 使用优雅的方式关闭应用,并设置了最长等待时间。

2.2、 对于 Spring Boot 2.3 之前的版本

如果你使用的是 Spring Boot 2.3 之前的版本,则需要手动引入 spring-boot-starter-actuator 并利用其提供的 /shutdown 端点来实现优雅停机。

首先,在你的 pom.xml 或者 build.gradle 中添加依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

然后,在 application.yml 中开启 /shutdown 端点:

management:endpoints:web:exposure:include: "shutdown"endpoint:shutdown:enabled: true

接下来,你可以通过发送 POST 请求到 /actuator/shutdown 来触发优雅停机。

2.3、 自定义优雅停机逻辑

如果默认的优雅停机行为不能满足需求,你还可以自定义优雅停机逻辑。例如,对于不同的 Web 容器(如 Tomcat、Jetty、Undertow),可以编写相应的代码来控制线程池的行为。

以 Tomcat 为例,你可以创建一个类实现 GracefulShutdownListenerApplicationListener<ContextClosedEvent> 接口,来定制化优雅停机过程。

package cn.gxm.multiinstancetest.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;/*** @author GXM* @version 1.0.0* @Description TODO* @createTime 2025年03月04日*/
@Slf4j
@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {/*** 优雅关机是否已开始*/private boolean isGracefulShutdownStarted = false;@Overridepublic void onApplicationEvent(ContextClosedEvent event) {// 执行你的业务逻辑log.info("Executing custom logic before graceful shutdown...");this.isGracefulShutdownStarted = true;}public boolean isGracefulShutdownStarted() {return isGracefulShutdownStarted;}
}

2.4、测试

下面的测试中, spring.lifecycle.timeout-per-shutdown-phase 值为30。

在这里插入图片描述

2.4.1、接口测试

1、写一个接口/sleep/{seconds}来测试。

package cn.gxm.multiinstancetest.controller;import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.net.InetAddress;
import java.net.UnknownHostException;/*** @author GXM* @version 1.0.0* @Description TODO* @createTime 2025年01月03日*/
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@GetMapping("/say")public String say() throws UnknownHostException {InetAddress localHost = InetAddress.getLocalHost();log.info("localhost: {}", localHost);return localHost.getHostAddress() + "_" + localHost.getHostName();}@GetMapping("/sleep/{seconds}")public String sleep(@PathVariable(value = "seconds") Integer seconds) {String startTime = DateUtil.now();try {Thread.sleep(seconds * 1000);} catch (Exception e) {log.error("sleep:", e);}String endTime = DateUtil.now();return startTime + "      " + endTime;}
}

2、第一种情况:在关机之前,请求接口http://127.0.0.1:9600/multi-instance-test/test/sleep/20,会导致睡眠20秒,接着马上在Idea关机程序,触发优雅关机。接口正常返回,并相差20秒,并且查看程序日志也是发现等待接口完成后才关机

在这里插入图片描述
在这里插入图片描述

3、第二种情况:在关机之前,请求接口http://127.0.0.1:9600/multi-instance-test/test/sleep/50,会导致睡眠50秒,接着马上在Idea关机程序,触发优雅关机。接口不会正常返回,并且查看程序日志发现关机就是相差30秒,所以如果你的接口处理的逻辑超过了设置的优雅关机的时间,它是不会管你的,任然会直接关机,会导致你的接口业务没有处理完成。

在这里插入图片描述

2.4.2、GracefulShutdownListener 测试

1、在 GracefulShutdownListener 类里通过sleep来模拟业务

    @Slf4j
@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {/*** 优雅关机是否已开始*/private boolean isGracefulShutdownStarted = false;@Overridepublic void onApplicationEvent(ContextClosedEvent event) {// 执行你的业务逻辑log.info("Executing custom logic before graceful shutdown...");this.isGracefulShutdownStarted = true;try {Thread.sleep(60 * 1000);} catch (Exception e) {log.error("sleep:", e);}log.info("Executing custom logic before graceful shutdown,end!");}public boolean isGracefulShutdownStarted() {return isGracefulShutdownStarted;}
}

2、第一种情况:设置上述代码的睡眠时间是20秒后启动程序,接着马上在Idea关机程序,触发优雅关机。日志正常打印,并相差20秒,并且查看程序日志也是发现等待睡眠完成后才关机

在这里插入图片描述

3、第二种情况:设置上述代码的睡眠时间是50秒后启动程序,接着马上在Idea关机程序,触发优雅关机。日志正常打印,并相差50秒,并且查看程序日志也是发现等待睡眠完成后才关机,所以如果你的逻辑超过了设置的优雅关机的时间,它是会等你完成,再关机。

在这里插入图片描述

3、GracefulShutdownListener 的逻辑是,要关机了,发出信号给你,你可以先处理,比如, 你在 GracefulShutdownListener 代码里面业务处理了50秒,那它就等你50秒,直到你自己的业务处理完成即50秒之后,然后再开始spring.lifecycletimeout-per-shutdown-phase30秒的计时,去执行自己的关机业务逻辑,为什么那么说呢,因为,你可以在GracefulShutdownListener 种处理的50秒内,请求接口,是可以接受返回的,如下

在这里插入图片描述

三、docker 镜像中优雅关机的配置

默认情况下,docker stop 命令会发送一个 SIGTERM 信号给容器中的主进程(PID 1),并等待一段时间(默认为 10 秒)以允许该进程正常关闭。如果这段时间内进程没有退出,Docker 会发送一个 SIGKILL 信号强制终止进程

3.1、错误示例

1、❌ 先给出一个原始的简单的"sh", "-c",这种方式,是收不到关机信号的,这是因为docker stop命令默认发送的是SIGTERM信号给容器的PID 1进程(在这个例子中是sh脚本),而不是直接给Java进程。由于sh脚本并不具备转发信号的能力,因此Java应用无法接收到终止信号,从而不能触发优雅关闭流程

FROM openjdk:17-jdk-alpine
VOLUME /tmp
ADD multi-instance-test-0.0.1-SNAPSHOT.jar run.jar
RUN sh -c 'touch /run.jar'
ENV JAVA_OPTS="-Xms512m -Xmx512m -server"
ENV PROFILE="test"
ENV APP_NAME="run.jar"ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS  -Djava.awt.headless=true -Duser.timezone=GMT+08 -Djava.security.egd=file:/dev/./urandom -jar /$APP_NAME --spring.profiles.active=test" ]

3.2、ENTRYPOINT 示例

2、修改上述的 ENTRYPOINT ,使用exec命令来替换当前进程(sh)为Java进程,这样Java进程就会成为PID 1,如下就可以收到信号了。

FROM openjdk:17-jdk-alpine
VOLUME /tmp
ADD multi-instance-test-0.0.1-SNAPSHOT.jar run.jar
RUN sh -c 'touch /run.jar'
ENV JAVA_OPTS="-Xms512m -Xmx512m -server"
ENV PROFILE="test"
ENV APP_NAME="run.jar"# 使用exec命令来替换当前进程(sh)为Java进程,这样Java进程就会成为PID 1
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -Djava.awt.headless=true -Duser.timezone=GMT+08 -Djava.security.egd=file:/dev/./urandom -jar /$APP_NAME --spring.profiles.active=$PROFILE"]

3.3、使用tini 作为 init 系统(推荐)

推荐理由:

  1. 信号转发与僵尸进程管理tini 不仅能确保信号(如 SIGTERM)被正确转发给子进程,还能处理僵尸进程,这使得它非常适合用于容器化应用。
  2. 简化配置:相比于直接操作 ENTRYPOINT 或编写复杂的启动脚本,使用 tini 更加简洁和易于维护。
  3. 兼容性和稳定性tini 是一个广泛使用的轻量级 init 系统,在许多 Docker 容器中都有成功应用的案例。

首先,在 Dockerfile 中添加安装 tini 的步骤,并调整 ENTRYPOINT 和 CMD 以使用 tini 启动 Java 应用。

FROM openjdk:17-jdk-alpine
VOLUME /tmp# 安装 tini
RUN apk add --no-cache tiniADD multi-instance-test-0.0.1-SNAPSHOT.jar run.jar
RUN sh -c 'touch /run.jar'
ENV JAVA_OPTS="-Xms512m -Xmx512m -server"
ENV PROFILE="test"
ENV APP_NAME="run.jar"# 使用 tini 启动 Java 应用
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["sh", "-c", "java $JAVA_OPTS -Djava.awt.headless=true -Duser.timezone=GMT+08 -Djava.security.egd=file:/dev/./urandom -jar /$APP_NAME --spring.profiles.active=$PROFILE"]

3.4、其他注意事项

  • Spring Boot 版本:确保你使用的 Spring Boot 版本支持优雅停机功能(2.3 及以上版本默认支持)。如果你使用的是较早版本,请参考之前的建议来启用或自定义优雅停机逻辑。
  • 超时设置:默认情况下,docker stop 命令会等待 10 秒让应用程序关闭。如果需要更长的时间,可以通过 -t 参数指定等待时间。例如,docker stop -t 30 my-running-app 将等待 30 秒。

其中超时设置,我再详细说一下,如果你在Spring Boot应用中设置了spring.lifecycle.timeout-per-shutdown-phase: 30s,那么为了确保Docker有足够的时间让Spring Boot完成其优雅关闭过程,在使用docker stop命令时,你应该设置一个至少为30秒的超时时间(通过-t参数)。

3.4.1 、具体原因

  1. Spring Boot优雅关闭机制:当Spring Boot接收到SIGTERM信号后,它会开始执行优雅关闭流程。这个过程包括但不限于停止监听HTTP请求、等待当前正在处理的请求完成、释放资源等。你配置的timeout-per-shutdown-phase: 30s意味着Spring Boot希望在这30秒内完成所有必要的关闭操作。

  2. Docker的SIGTERM和SIGKILL行为

    • 当你执行docker stop <container_id>时,Docker会向容器内的主进程发送SIGTERM信号。
    • 默认情况下,Docker会等待10秒(可以通过-t参数自定义)来允许容器内的进程自行终止。
    • 如果在这个时间内进程没有退出,Docker将发送SIGKILL信号强制终止该进程。

因此,如果Docker的超时时间(默认或通过-t指定)小于Spring Boot所需的关闭时间(例如小于30秒),那么Spring Boot可能无法在Docker强制终止之前完成所有的关闭操作,导致部分关闭逻辑未被执行。

3.4.2、实践建议

为了确保Spring Boot应用能够顺利完成其优雅关闭流程,可以采取以下措施之一:

3.4.2.1、方法1:增加Docker的停止超时时间

当你使用docker stop命令时,指定一个至少为30秒的超时时间:

docker stop -t 30 <container_id>

这将给Spring Boot足够的时间来完成其关闭流程。

3.4.2.2、方法2:在启动容器时设置停止超时时间

你也可以在启动容器时通过--stop-timeout选项来设置超时时间:

docker run --stop-timeout 30 ...
3.4.2.3、方法3:调整Spring Boot的关闭超时时间

如果你发现30秒对于你的应用来说过长,可以考虑缩短Spring Boot的关闭超时时间。但是请注意,这需要确保在较短的时间内能够完成所有必要的关闭操作,否则可能会导致资源泄漏或其他问题。

3.4.2.4 示例

假设你已经配置了Spring Boot的关闭超时时间为30秒:

spring:lifecycle:timeout-per-shutdown-phase: 30s

那么在停止容器时,你应该使用如下命令:

docker stop -t 30 my-spring-boot-container

这样,Docker会给Spring Boot足够的时间(30秒)来完成其优雅关闭流程,避免因超时导致的强制终止。

只有日志显示了完整的优雅关闭的日志才是真的没问题

在这里插入图片描述

相关文章:

SpringBoot优雅关机,监听关机事件,docker配置

Spring Boot 提供了多种方法来实现优雅停机&#xff08;Graceful Shutdown&#xff09;&#xff0c;这意味着在关闭应用程序之前&#xff0c;它会等待当前正在处理的请求完成&#xff0c;并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下&#xff1a; …...

网络基础(一)【网络发展/认识协议/网络 VS 系统/以太网通信原理/重谈协议/网络中的地址管理】

网络基础&#xff08;一&#xff09; 1. 网络的发展2. 认识协议3. 网络 VS 系统4. 以太网通信原理5. 重谈协议6. 网络中的地址管理 1. 网络的发展 最开始时&#xff0c;计算机之间相互独立。 但是为了协作完成一些任务&#xff0c;就产生了计算机之间相互通讯的需求&#xff0c…...

PostgreSQL、SQL Server和MySQL数据库性能调优与故障排除技术

通过结合具体技术特性与工具链的深度使用&#xff0c;可系统化提升数据库性能和稳定性。建议根据实际负载特征制定监控-分析-优化的闭环管理流程。 数据库技术&#xff1a; PostgreSQL 13&#xff1a;逻辑复制、分区表、并行查询、监控工具&#xff08;如pg_stat_statements、…...

本地YARN集群部署

请先完成HDFS的前置部署&#xff0c;部署方式可查看:本地部署HDFS集群https://blog.csdn.net/m0_73641796/article/details/145998092?spm1001.2014.3001.5502 部署说明 组件配置文件启动进程备注Hadoop HDFS需修改 需启动: NameNode作为主节点 DataNode作为从节点 Secondary…...

Redis数据结构——list

目录 列表命令 lpush lrange lpushx rpush rpushx lpop rpop lindex linsert llen lrem ltrim lset blpop / brpop 命令总结 编码方式 list相当于数组或者顺序表,但并不是简单的数组&#xff0c;更接近于C中的"双端队列"(deque)。 最左侧的下标…...

World of Warcraft [CLASSIC] BigFoot BiaoGe

World of Warcraft [CLASSIC] BigFoot BiaoGe 金团表格插件 设置60秒拍卖装备时间 ALT 鼠标左键&#xff0c;点击装备&#xff0c;弹出对话框&#xff0c;填写 1&#xff09;拍卖时间默认60秒&#xff0c;起拍价&#xff0c; 2&#xff09;点击【开始拍卖】 团队所有安装了…...

CentOS Docker 安装指南

CentOS Docker 安装指南 引言 Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包他们的应用以及应用的依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。Docker 容器是完全使用沙箱机制&#xff0c;相互之…...

PHP:phpstudy无法启动MySQL服务问题解决

文章目录 一、问题说明二、解决问题 一、问题说明 我的Windows10系统&#xff0c;之前安装过MySQL5.7的版本。 然后&#xff0c;用phpstudy安装MySQL8&#xff0c;并启动MySQL8。 发生无法启动的情况。 二、解决问题 1、删除本地MySQL7的服务 net stop MySQL //这里的服务名…...

【电控笔记z29】扰动估测器DOB估测惯量J-摩擦系数B

基本原理 扰动估测器的核心思想是通过向电机系统施加特定的扰动信号&#xff0c;观察系统响应的变化&#xff0c;然后利用系统的动态模型和控制理论来估计未知参数&#xff0c;如惯量和摩擦系数 。一般基于电机的运动方程建立数学模型&#xff0c;结合观测到的电机实际运行数据…...

STM32-I2C通信外设

目录 一&#xff1a;I2C外设简介 二&#xff1a;I2C外设数据收发 三&#xff1a;I2C的复用端口 四&#xff1a;主机发送和接收 五&#xff1a;硬件I2C读写MPU6050 相关函数&#xff1a; 1.I2C_ GenerateSTART 2.I2C_ GenerateSTOP 3.I2C_ AcknowledgeConfig 4.I2C…...

计算机二级MS之PPT

声明&#xff1a;跟着大猫和小黑学习随便记下一些笔记供大家参考&#xff0c;二级考试之前将持续更新&#xff0c;希望大家二级都能轻轻松松过啦&#xff0c;过了二级的大神也可以在评论区留言给点建议&#xff0c;感谢大家&#xff01;&#xff01; 文章目录 考题难点1cm25px…...

Spring Boot 3 整合 MinIO 实现分布式文件存储

引言 文件存储已成为一个做任何应用都不可回避的需求。传统的单机文件存储方案在面对大规模数据和高并发访问时往往力不从心&#xff0c;而分布式文件存储系统则提供了更好的解决方案。本篇文章我将基于Spring Boot 3 为大家讲解如何基于MinIO来实现分布式文件存储。 分布式存…...

C++ Primer 交换操作

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…...

分布式中间件:Redis介绍

目录 Redis 概述 Redis 的特点 高性能 丰富的数据结构 持久化 分布式特性 简单易用 Redis 的数据结构 字符串&#xff08;String&#xff09; 哈希&#xff08;Hash&#xff09; 列表&#xff08;List&#xff09; 集合&#xff08;Set&#xff09; 有序集合&…...

软件测试的基础入门(二)

文章目录 一、软件&#xff08;开发&#xff09;的生命周期什么是生命周期软件&#xff08;开发&#xff09;的生命周期需求分析计划设计编码测试运行维护 二、常见的开发模型瀑布模型流程优点缺点适应的场景 螺旋模型流程优点缺点适应的场景 增量模型和迭代模型流程适应的场景…...

学之思社区版考试系统docker-compose部署

参考 开源项目-Docker部署学之思管理系统 安装docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Bas…...

深度优先搜索(DFS)和广度优先搜索(BFS)——c#实现

一、深度优先搜索&#xff08;DFS&#xff09; 原理&#xff1a; 沿着分支尽可能深入&#xff0c;直到到达叶子节点&#xff0c;然后回溯探索其他分支 类似走迷宫时优先选择一条路走到黑&#xff0c;碰壁再回退 数据结构&#xff1a;栈&#xff08;Stack&#xff09;或递归实…...

什么是hive

Apache Hive 是一个基于 Hadoop 生态系统构建的数据仓库工具&#xff0c;主要用于处理和分析大规模的结构化数据。它允许用户通过类似 SQL 的查询语言&#xff08;HiveQL&#xff09;进行数据操作&#xff0c;而无需直接编写复杂的 MapReduce 程序。以下是 Hive 的核心特点和应…...

JVM详解

目录 一.JVM的概念 1. 什么是JVM? 2.JVM用来干什么? 二JVM运行流程 JVM执⾏流程 2.1类加载机制 2.2类加载机制带来了哪些好处? 2.3类加载的过程是什么? 2.3.1加载 2.3.2验证 2.3.3准备阶段 2.3.4解析阶段 符号引⽤ 直接引⽤ 2.3.5初始化阶段 2.4类加载器 什么…...

PCA(主成分分析)核心原理

一、PCA&#xff08;主成分分析&#xff09;核心原理 即主成分分析技术&#xff0c;又称主分量分析技术&#xff0c;旨在利用降维的思想&#xff0c;把多指标转化为少数几个综合指标。在统计学中&#xff0c;主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换…...

DeepSeek私有化部署6:openEuler 24.03-LTS-SP1安装Open WebUI

Open WebUI是一个 Open WebUI 是一个可扩展的、功能丰富、用户友好的自托管 AI 平台&#xff0c;专为完全离线运行而设计。 它支持多种 LLM 运行环境&#xff0c;包括 Ollama 和 OpenAI 兼容的 API&#xff0c;并内置了用于 RAG 的推理引擎&#xff0c;是一个强大的 AI 部署解决…...

【一文学会 HTML5】

目录 HTML概述基本概念HTML 发展历程HTML 基本结构 网页基本标签标题标签&#xff08;<h1> - <h6>&#xff09;段落标签&#xff08;<p>&#xff09;换行标签&#xff08;<br>&#xff09;水平线标签&#xff08;<hr>&#xff09;注释&#xff0…...

前端题目类型

HTMLCSS常见面试题 HTML标签有哪些行内元素 img、picture、span、input、textarea、select、label 说说你对元素语义化的理解 元素语义化就是用正确的元素做正确的事情。虽然理论上所有html元素都可通过css样式实现相同效果&#xff0c;但这样会使事情复杂化&#xff0c;所以需…...

nodejs学习——nodejs和npm安装与系统环境变量配置及国内加速

nodejs和npm安装与系统环境变量配置及国内加速 下载node-v22.14.0-x64.msi 建议修改为非C盘文件夹 其它步骤&#xff0c;下一步&#xff0c;下一步&#xff0c;完成。 打开CMD窗口查看安装详情 $ node -v v22.14.0 $ npm -v 10.9.2$ npm config list创建node_global和node_c…...

[视频编码]rkmpp 实现硬件编码

mpi_enc_test的命令参数描述说明 命令参数的描述说明如下&#xff1a; 命令参数 描述说明 -i 输入的图像文件。 -o 输出的码流文件。 -w 图像宽度&#xff0c;单位为像素。 -h 图像高度&#xff0c;单位为像素。 -hstride 垂直方向相邻两行之间的距离&#xff0c;单…...

Vue3实战学习(Vue3的基础语法学习与使用(超详细))(3)

目录 &#xff08;1&#xff09;Vue3工程环境准备、项目基础脚手架搭建详细教程。(博客链接) &#xff08;2&#xff09;Vue3的基础语法学习与使用。 &#xff08;1&#xff09;"{{}}"绑定数据。 <1>ref()函数定义变量——绑定数据。 <2>reactive({...})…...

基于multisim的花样彩灯循环控制电路设计与仿真

1 课程设计的任务与要求 &#xff08;一&#xff09;、设计内容&#xff1a; 设计一个8路移存型彩灯控制器&#xff0c;基本要求&#xff1a; 1. 8路彩灯能演示至少三种花型&#xff08;花型自拟&#xff09;&#xff1b; 2. 彩灯用发光二极管LED模拟&#xff1b; 3. 选做…...

EasyRTC嵌入式视频通话SDK的跨平台适配,构建web浏览器、Linux、ARM、安卓等终端的低延迟音视频通信

1、技术背景 WebRTC是一项开源项目&#xff0c;旨在通过简单的API为浏览器和移动应用程序提供实时通信&#xff08;RTC&#xff09;功能。它允许在无需安装插件或软件的情况下&#xff0c;实现点对点的音频、视频和数据传输。 WebRTC由三个核心组件构成&#xff1a; GetUserM…...

【CSS】gap 属性详解

文章目录 一、什么是 gap 属性1. 定义2. 语法3. 默认值 二、gap 属性的基本用法1. 网格布局中的应用2. 弹性布局中的应用3. 单值和双值的区别 三、gap 属性的实际应用场景1. 表单布局优化2. 图片网格布局 四、gap 的注意事项1. 浏览器兼容性2. 替代 margin 的场景3. 不同布局的…...

【招聘精英】

我们公司是一个位于石家庄的一个科技型新型技术公司。主要做人力资源、用工、科技等方面。 有意向回石家庄的或者已经在石家庄的技术大咖、软件大牛、产品大佬、UI大神可以来了解一下。 现在招聘 高级前端开发 高级java开发 其他岗位也可以联系。 有意向的朋友可以私信我。 -…...

qt 操作多个sqlite文件

qt 操作多个sqlite文件 Chapter1 qt 操作多个sqlite文件1. 引入必要的头文件2. 创建并连接多个SQLite数据库3. 代码说明4. 注意事项 Chapter2 qt 多线程操作sqlite多文件1. 引入必要的头文件2. 创建数据库操作的工作线程类3. 在主线程中创建并启动多个工作线程4. 代码说明5. 运…...

【自学笔记】Numpy基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Numpy基础知识点总览目录1. 简介Numpy是什么为什么使用Numpy 2. 数组对象&#xff08;ndarray&#xff09;创建数组数组的属性数组的形状操作 3. 数组的基本操作数组…...

DP 问题 -- LQR中的DP问题

深入地介绍线性二次调节问题&#xff08;Linear Quadratic Regulator, LQR&#xff09;&#xff0c;并详细说明它作为动态规划&#xff08;DP&#xff09;的一个经典应用问题的求解过程。 &#x1f4cc; 一、LQR问题定义&#xff08;最优控制视角&#xff09; LQR 问题是一种特…...

Win7重装不翻车!ISO镜像安全下载渠道+BIOS设置避雷手册

一、写在前面&#xff1a;为什么你需要这份教程&#xff1f; 当电脑频繁蓝屏、系统崩溃甚至无法开机时&#xff0c;重装系统可能是最后的救命稻草。但市面上的教程往往存在三大痛点&#xff1a; ⚠️ 镜像来源不明导致系统被植入后门 ⚠️ 启动盘制作失败反复折腾 ⚠️ 操作失…...

CEF在MFC上的示例工程

CEF 在 MFC 中的使用 工程配置 1、首先创建一个MFC对话框工程 创建完运行测试效果如下 2、MFC工程引入CEF库 将 CEF 目录下的 cef子目录下载解压后放到MFC工程中&#xff1a; 然后在VS中对工程右键 -> 属性 -> C/C -> 常规 -> 附加包含目录&#xff0c;添加“.\…...

#UVM# 关于 config_db 机制中的直线非直线设置和获取讲解

在 UVM 验证环境中,uvm_config_db 是一种强大的机制,用于在不同组件之间传递配置参数。实际应用中,我们经常使用直线和非直线的设置与获取。今天,着重回忆一下这些内容,希望实际中更加方便的使用。 UVM 树结构示例 假设 UVM 树结构如下: uvm_test_top ├── env │ …...

[PWNME 2025] PWN 复现

这种比赛得0也不容易&#xff0c;前边暖声还是能作的。 GOT 指针前溢出&#xff0c;可以溢出到GOT表&#xff0c;然后把后门写上就行 Einstein 这个拿到WP也没复现成&#xff0c;最后自己改了一下。 int __cdecl handle() {int offset; // [rsp8h] [rbp-38h] BYREFunsigne…...

Java网络编程,多线程,IO流综合项目一一ChatBoxes

Java网络编程&#xff0c;多线程&#xff0c;IO流综合小项目一一ChatBoxes 作者&#xff1a;blue 时间&#xff1a;2025.3.7 文章目录 Java网络编程&#xff0c;多线程&#xff0c;IO流综合小项目一一ChatBoxes1.项目介绍2.项目源码剖析2.1客户端源码2.2客户端Sender线程Runn…...

大数据、人工智能、云计算、物联网、区块链序言【大数据导论】

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;大数据入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 这是目…...

【算法 C/C++】一维前缀和

2025 - 03 - 08 - 第 68 篇 Author: 郑龙浩 / 仟濹 【一维前缀和】 文章目录 前缀和与差分 - 我的博客1 大体介绍2 计算某些区间的和( 不使用前缀和 )3 计算某些区间的和( 使用前缀和 ) 前缀和与差分 - 我的博客 一维前缀和 【算法 C/C】一维前缀和 一维差分 【算法 C/C】一维…...

【C++】:STL详解 —— 红黑树

目录 平衡二叉查找树 红黑树的概念 红黑树的五大性质 红黑树的效率 红黑树和AVL树的比较 插入与删除操作 内存与实现复杂度 经典性能数据对比 总结 对旋转的基本理解 旋转的作用 左旋&#xff08;Left Rotation&#xff09; 右旋&#xff08;Right Rotation&#xf…...

【A2DP】SBC 编解码器互操作性要求详解

目录 一、SBC编解码器互操作性概述 二、编解码器特定信息元素(Codec Specific Information Elements) 2.1 采样频率(Sampling Frequency) 2.2 声道模式(Channel Mode) 2.3 块长度(Block Length) 2.4 子带数量(Subbands) 2.5 分配方法(Allocation Method) 2…...

Mysql的卸载安装配置以及简单使用

MySQL其它问题已经更新在&#xff1a;MySQL完善配置---可视化-CSDN博客 一、卸载 ①控制面板卸载 ②C盘隐藏项目>ProgramData>mysql相关文件夹&#xff0c;还有Program file下的MySQL文件夹 ③开始菜单栏搜索>服务&#xff0c;找到MySQL相关服务删除&#xff0c;如果再…...

Ubuntu 下 nginx-1.24.0 源码分析 (1)

main 函数在 src\core\nginx.c int ngx_cdecl main(int argc, char *const *argv) {ngx_buf_t *b;ngx_log_t *log;ngx_uint_t i;ngx_cycle_t *cycle, init_cycle;ngx_conf_dump_t *cd;ngx_core_conf_t *ccf;ngx_debug_init(); 进入 main 函数 最…...

驱动开发系列43 - Linux 显卡KMD驱动代码分析(四)- DRM设备操作

一:概述 DRM(Direct Rendering Manager)是Linux内核中的一个子系统,主要负责图形硬件的管理与图形渲染的加速。它为图形驱动提供了一个统一的接口,可以使用户空间程序与图形硬件进行直接交互,而无需通过X服务器或Wayland等显示管理器。DRM不仅用于管理显卡,还处理视频输…...

PAT乙级真题(2014·冬)

大纲 1031、查验身份证-&#xff08;解析&#xff09;-简单题 1032、挖掘机技术哪家强-&#xff08;解析&#xff09;-细节题(┬┬﹏┬┬)&#xff0c;太抠细节了 1033、旧键盘打字-&#xff08;解析&#xff09;-输入格式&#xff01;这才是重点(┬┬﹏┬┬)&#xff0c;让…...

快速使用MASR V3版不能语音识别框架

前言 本文章主要介绍如何快速使用MASR语音识别框架训练和推理&#xff0c;本文将致力于最简单的方式去介绍使用&#xff0c;如果使用更进阶功能&#xff0c;还需要从源码去看文档。仅需三行代码即可实现训练和推理。 源码地址&#xff1a;https://github.com/yeyupiaoling/MA…...

学习笔记:Python网络编程初探之基本概念(一)

一、网络目的 让你设备上的数据和其他设备上进行共享&#xff0c;使用网络能够把多方链接在一起&#xff0c;然后可以进行数据传递。 网络编程就是&#xff0c;让在不同的电脑上的软件能够进行数据传递&#xff0c;即进程之间的通信。 二、IP地址的作用 用来标记唯一一台电脑…...

硬件基础(4):(2)认识ADC参考电压

文章目录 1. **ADC参考电压的定义**2. **如何影响采样值**3. **参考电压的选择**4. **如何选择参考电压**5. **总结** **ADC参考电压&#xff08;Vref&#xff09;**是用于定义ADC采样范围的一个重要参数&#xff0c;以下是对 ADC 参考电压的详细解释&#xff1a; 1. ADC参考电…...

项目中同时使用Redis(lettuce)和Redisson的报错

温馨提示&#xff1a;图片有点小&#xff0c;可以放大页面进行查看... 问题1&#xff1a;版本冲突 直接上图&#xff0c;这个错表示依赖版本不匹配问题&#xff0c;我本地SpringBoot用的是2.7&#xff0c;但是Redisson版本用的3.32.5。 我们通过点击 artifactId跟进去 发现它…...