Log4j2-29-log4j2 discard policy 极端情况下的丢弃策略 同步+异步配置的例子

Log4j2异步日志、同步日志和混合日志的配置详解

Log4j 2中记录日志的方式有同步日志和异步日志两种方式,其中异步日志又可分为使用AsyncAppender和使用AsyncLogger两种方式。

异步日志(性能最好,推荐使用)

异步日志情况下,增加 Disruptor 队列长度并配置队列堵塞丢弃策略从可以增加高并发下的性能,实现如下:

(1) jvm 参数:-DLog4jAsyncQueueFullPolicy=Discard -DLog4j2.asyncLoggerRingBufferSize:指定队列的长度(根据实际压测情况调试,一般不会指定长度)

(2) 或者在log4j2.component.properties中配置丢弃策略:

log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
log4j2.asyncLoggerRingBufferSize=根据实际压测情况调试

队列大小源码:

final class DisruptorUtil {private static final Logger LOGGER = StatusLogger.getLogger();private static final int RINGBUFFER_MIN_SIZE = 128;private static final int RINGBUFFER_DEFAULT_SIZE = 256 * 1024;private static final int RINGBUFFER_NO_GC_DEFAULT_SIZE = 4 * 1024;
......static int calculateRingBufferSize(final String propertyName) {
// 队列大小      
int ringBufferSize = Constants.ENABLE_THREADLOCALS ? RINGBUFFER_NO_GC_DEFAULT_SIZE : RINGBUFFER_DEFAULT_SIZE;final String userPreferredRBSize = PropertiesUtil.getProperties().getStringProperty(propertyName,String.valueOf(ringBufferSize));try {int size = Integers.parseInt(userPreferredRBSize);if (size < RINGBUFFER_MIN_SIZE) {size = RINGBUFFER_MIN_SIZE;LOGGER.warn("Invalid RingBufferSize {}, using minimum size {}.", userPreferredRBSize,RINGBUFFER_MIN_SIZE);}ringBufferSize = size;} catch (final Exception ex) {LOGGER.warn("Invalid RingBufferSize {}, using default size {}.", userPreferredRBSize, ringBufferSize);}return Integers.ceilingNextPowerOfTwo(ringBufferSize);}
...

同步日志

所谓同步日志,即当输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑语句。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration><Properties><!-- 日志输出级别 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error级别日志 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在当前目录下创建名为log目录做日志存放的目录 --><Property name="LOG_HOME" value="./log"/><!-- 档案日志存放目录 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日志文件大小,超过这个大小将被压缩 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天以内的日志 --><Property name="LOG_DAYS" value="15"/><!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval属性用来指定多久滚动一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties><Appenders><!-- 控制台输出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--输出日志的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console><!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档--><RollingRandomAccessFile name="RollingRandomAccessFileInfo" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz"><Filters><!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--如果是info\warn输出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile><!--只记录error级别以上的日志,与info级别的日志分不同的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile></Appenders><Loggers><!-- 开发环境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>--><!-- 测试,生产环境使用 --><Root level="${LOG_INFO_LEVEL}"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers></Configuration>

混合同步和异步日志

Log4j-2.9及更高版本在类路径上需要 disruptor-3.3.4.jar 或更高版本。

在Log4j-2.9之前,需要disruptor-3.0.0.jar或更高版本。无需将系统属性“Log4jContextSelector”设置为任何值。

可以在配置中组合同步和异步记录器。这为您提供了更大的灵活性,但代价是性能略有下降(与使所有记录器异步相比)。

使用 <asyncRoot><asyncLogger> 配置元素指定需要异步的记录器。

配置只能包含一个根记录器(<root><asyncRoot> 元素),但是可以组合异步和非异步记录器。

例如,包含 <asyncLogger> 元素的配置文件也可以包含 <root> 和同步记录器的元素。

默认情况下,异步记录器不会将位置传递给 I/O 线程。

如果您的某个布局或自定义过滤器需要位置信息,则需要在所有相关记录器的配置中设置“includeLocation = true”,包括根记录器。

首先引入disruptor依赖

<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version>
</dependency>

混合异步记录器的配置可能如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration><Properties><!-- 日志输出级别 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error级别日志 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在当前目录下创建名为log目录做日志存放的目录 --><Property name="LOG_HOME" value="./log"/><!-- 档案日志存放目录 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日志文件大小,超过这个大小将被压缩 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天以内的日志 --><Property name="LOG_DAYS" value="15"/><!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval属性用来指定多久滚动一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties><Appenders><!-- 控制台输出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--输出日志的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console><!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档--><!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false--><RollingRandomAccessFile name="RollingRandomAccessFileInfo" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"><Filters><!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--如果是info\warn输出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile><!--只记录error级别以上的日志,与info级别的日志分不同的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile></Appenders><Loggers><!-- 开发环境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>--><!-- 测试,生产环境使用 --><!-- 当使用<asyncLogger> or <asyncRoot>时,无需设置系统属性"Log4jContextSelector" --><AsyncLogger name="com.jourwon" level="${LOG_INFO_LEVEL}" additivity="false"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></AsyncLogger><Root level="${LOG_INFO_LEVEL}"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers></Configuration>

异步日志(性能最好,推荐使用)

Log4j-2.9及更高版本在类路径上需要disruptor-3.3.4.jar或更高版本。

在Log4j-2.9之前,需要disruptor-3.0.0.jar或更高版本。这是最简单的配置,并提供最佳性能。要使所有记录器异步,

请将disruptor jar添加到类路径,并将系统属性log4j2.contextSelector设置 为org.apache.logging.log4j.core.async.AsyncLoggerContextSelector。

默认情况下,异步记录器不会将位置传递给 I/O 线程。

如果您的某个布局或自定义过滤器需要位置信息,则需要在所有相关记录器的配置中设置“includeLocation = true”,包括根记录器。

首先引入disruptor依赖

<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version>
</dependency>

配置

第二步(方式一): 在src/java/resources目录添加log4j2.component.properties配置文件

# 设置异步日志系统属性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

第二步(方式二): 通过JVM参数实现

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration><Properties><!-- 日志输出级别 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error级别日志 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在当前目录下创建名为log目录做日志存放的目录 --><Property name="LOG_HOME" value="./log"/><!-- 档案日志存放目录 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日志文件大小,超过这个大小将被压缩 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天以内的日志 --><Property name="LOG_DAYS" value="15"/><!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval属性用来指定多久滚动一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties><Appenders><!-- 控制台输出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--输出日志的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console><!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档--><!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false--><RollingRandomAccessFile name="RollingRandomAccessFileInfo" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"><Filters><!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--如果是info\warn输出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile><!--只记录error级别以上的日志,与info级别的日志分不同的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile></Appenders><Loggers><!-- 开发环境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>--><!-- 测试,生产环境使用 --><Root level="${LOG_INFO_LEVEL}" includeLocation="false"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers></Configuration>

当配置AsyncLoggerContextSelector作为异步日志时,请确保在配置中使用普通的 <root><logger> 元素。

AsyncLoggerContextSelector将确保所有记录器都是异步的,使用的机制与配置 <asyncRoot><asyncLogger> 时的机制不同。

通过 log.info(“是否为异步日志:{}”, AsyncLoggerContextSelector.isSelected()); 可以查看是否为异步日志。

日志输出方式注释
sync同步打印日志,日志输出与业务逻辑在同一线程内,当日志输出完毕,才能进行后续业务逻辑操作
Async Appender异步打印日志,内部采用ArrayBlockingQueue,对每个AsyncAppender创建一个线程用于处理日志输出。
Async Logger异步打印日志,采用了高性能并发框架Disruptor,创建一个线程用于处理日志输出。

chat

Q1-介绍一下 log4j2 的丢弃策略

log4j2 是一个流行的 Java 日志框架,它提供了丰富的配置选项来管理日志输出。

在 log4j2 中,丢弃策略(Discarding Strategy)用于处理日志事件超过指定阈值时的行为。

log4j2 提供了多种丢弃策略,以下是其中一些常用的策略:

  1. DefaultDiscardPolicy(默认策略):当日志事件超过日志队列的容量时,新的日志事件将被丢弃,不会进一步处理。

  2. DiscardOldestPolicy(丢弃最旧策略):当日志事件超过日志队列的容量时,队列中最旧的日志事件将被丢弃,为新的日志事件腾出空间。

  3. DiscardPolicy(丢弃策略):当日志事件超过日志队列的容量时,新的日志事件将被丢弃,不会进一步处理。与 DefaultDiscardPolicy 的区别在于,DiscardPolicy 不会打印任何警告消息。

  4. AsyncQueueFullPolicy(异步队列满策略):当异步日志队列满时,新的日志事件将被丢弃,并触发一个警告消息。

这些丢弃策略可以通过 log4j2 的配置文件进行设置。您可以根据具体的需求选择适合的丢弃策略来管理日志事件的处理。请注意,选择适当的丢弃策略需要权衡日志事件的重要性和系统资源的利用情况。

请注意,上述策略仅为常见的丢弃策略示例,log4j2 还提供了其他自定义策略的选项。具体的配置和使用方式可以参考 log4j2 的官方文档或相关资源。

Q2-log4j2 异步输出,如何配置对应的丢弃策略?系统的默认值是什么?

在 log4j2 中配置异步输出和对应的丢弃策略需要进行以下步骤:

  1. 配置异步日志记录器:在 log4j2 的配置文件中,可以使用 <AsyncLogger> 元素来配置异步输出。

例如:

<AsyncLogger name="com.example.MyLogger" level="info" additivity="false"><AppenderRef ref="MyAppender"/>
</AsyncLogger>

在上述示例中,我们配置了一个名为 “com.example.MyLogger” 的异步日志记录器,并指定了日志级别为 “info”,以及要使用的 Appender。

  1. 配置丢弃策略:在 <AsyncLogger> 元素中,可以使用 <AsyncQueueFullPolicy> 元素来配置丢弃策略。

例如:

<AsyncLogger name="com.example.MyLogger" level="info" additivity="false"><AppenderRef ref="MyAppender"/><AsyncQueueFullPolicy><DiscardOldestMessage/></AsyncQueueFullPolicy>
</AsyncLogger>

在上述示例中,我们在 <AsyncLogger> 元素中添加了 <AsyncQueueFullPolicy> 元素,并指定了丢弃策略为 “DiscardOldestMessage”,即丢弃最旧的日志事件。

  1. 默认丢弃策略:log4j2 的默认丢弃策略是 DefaultAsyncQueueFullPolicy ,它会直接丢弃新的日志事件。

需要注意的是,丢弃策略的配置可以根据具体需求进行调整。

除了 <DiscardOldestMessage> 策略外,log4j2 还提供了其他丢弃策略,如 <DiscardNewestMessage> (丢弃最新的日志事件)和 <DiscardThresholdMessage> (丢弃超过指定阈值的日志事件)等。

请注意,具体的配置和使用方式可以参考 log4j2 的官方文档或相关资源,以确保正确配置异步输出和丢弃策略。

Q3-log4j2 中 log4j2.component.properties 配置丢弃策略怎么配置?系统的默认值是什么?

在 log4j2 中,您可以使用 log4j2.component.properties 文件来配置丢弃策略。以下是配置丢弃策略的步骤:

  1. 创建 log4j2.component.properties 文件:在您的 log4j2 配置文件所在的目录中,创建一个名为 log4j2.component.properties 的文件。

  2. 配置丢弃策略:在 log4j2.component.properties 文件中,添加以下配置行来指定丢弃策略:
    AsyncQueueFullPolicy=org.apache.logging.log4j.core.async.DefaultAsyncQueueFullPolicy
    在上述示例中,我们将丢弃策略设置为默认的 DefaultAsyncQueueFullPolicy。

  3. 系统默认值:log4j2 的默认丢弃策略是 DefaultAsyncQueueFullPolicy,它会直接丢弃新的日志事件。

需要注意的是,log4j2.component.properties 文件中的配置将适用于整个 log4j2 配置,而不仅仅是丢弃策略。您可以在该文件中添加其他属性和配置,以满足您的需求。

请注意,具体的配置和使用方式可以参考 log4j2 的官方文档或相关资源,以确保正确配置丢弃策略和其他组件属性。

参考资料在这里插入图片描述

Log4j2异步日志、同步日志和混合日志的配置详解

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出HBase:一文理解HBase基础概念(列存储、时间戳、key-value)、架构特点以及适合的使用场景

文章目录 一. HBase 数据模型1. 行存储与列式存储1.1. 行存储1.2. 列存储 2. HBase 数据模型2.1. 模型概览2.2. 列与列族2.3. 时间戳&#xff1a;定义数据版本2.4. HBase的Key-Value 三. HBase架构1. HBase读写流程简述2. HRegionServer内部内部数据流转&#xff1a;HRegion &l…

Web性能优化之如何评估网页性能——性能指标和度量工具介绍

前言 用户在访问 web 网页时&#xff0c;大部分都希望网页能够在一秒完成。事实上&#xff0c;加载时间每多 1 秒&#xff0c;就会流失 7%的用户。如果时间超过 8s 用户就会感到不耐烦、会放弃访问。这也就是著名的 “8秒原则”。 虽然当今设备及网络环境都大幅提升&#xff…

【Spark系列3】RDD源码解析实战

本文主要讲 1、什么是RDD 2、RDD是如何从数据中构建 一、什么是RDD&#xff1f; RDD&#xff1a;弹性分布式数据集&#xff0c;Resillient Distributed Dataset的缩写。 个人理解&#xff1a;RDD是一个容错的、并行的数据结构&#xff0c;可以让用户显式的将数据存储到磁盘…

DVI接口如何连接HDMI接口显示器?DVI转HDMI转换器DHA

DVI转HDMI转换器DHA简介 DVI转HDMI转换器DHA能够将DVI信号和R/L音频信号输入转换成HDMI信号输出,独特的功能使其顺畅地整合到家庭影院中&#xff0c;并且播放出高品质的图像。主要用于数据监控中心、大型会议展示中心、学校及各个公司 DVI转HDMI转换器DHA特点 01.支持分辨率4K…

【TCP】三次握手(建立连接)

前言 在网络通信的世界里&#xff0c;可靠传输协议&#xff08;TCP&#xff09;扮演着重要的角色&#xff0c;它保证了数据包能够按顺序、完整地从发送端传送到接收端。TCP协议中有一个至关重要的机制——三次握手。这一过程确保了两个TCP设备在开始数据传输之前建立起一个稳定…

内衣洗衣机有必要买吗?最好用的迷你洗衣机推荐

随着内衣洗衣机的流行&#xff0c;很多小伙伴在纠结该不该入手一款内衣洗衣机&#xff0c;专门来洗一些贴身衣物&#xff0c;答案是非常有必要的&#xff0c;因为我们现在市面上的大型洗衣机只能做清洁&#xff0c;无法对我们的贴身衣物进行一个高强度的清洁&#xff0c;而小小…

手写分布式存储系统v0.1版本

引言 这是手写分布式存储系统v0.1版本&#xff0c;只有一个目标就是支持通过tcp接收数据并落地到磁盘文件(单机模式)&#xff0c;那接下来就开始吧 设计 实现一个系统&#xff0c;设计是最过瘾的过程没有之一&#xff0c;类似你搭积木前在脑海设计构建一副大致的“雏形”&am…

力扣hot100 最小路径和 多维DP 滚动数组 一题多解

Problem: 64. 最小路径和 文章目录 思路&#x1f496; 朴素版&#x1f496; 空间优化版 思路 &#x1f468;‍&#x1f3eb; 路飞 &#x1f496; 朴素版 ⏰ 时间复杂度: O ( n m ) O(nm) O(nm) &#x1f30e; 空间复杂度: O ( n m ) O(nm) O(nm) class Solution {public …

查看Windows 所有账户方法

目标 了解Windows查看所有账户的方法 方法 方法1&#xff1a;本地和用户组 按下Win X键&#xff0c;选择“计算机管理”。在计算机管理界面的左侧面板中&#xff0c;展开“系统工具” -> “本地用户和组” -> “用户”。在右侧窗口中&#xff0c;查看列出的所有用户账…

数据结构+算法(第01篇):走下神坛吧!算法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

科技云报道:新趋势下,国产数据库或“春山可望”

科技云报道原创。 从540亿元到1286亿元——这是中国通信标准化协会大数据技术标准推进委员会针对中国数据库行业给出的一份预测报告。 报告指出&#xff0c;未来五年&#xff0c;中国数据库行业将从百亿级市场跨越成为千亿级市场。 最近两年&#xff0c;中国的数据库行业似乎…

Docker核心教程

1. 概述 官网&#xff1a;https://docs.docker.com/ Docker Hub 网站&#xff1a;https://hub.docker.com/ 容器较为官方的解释&#xff1a; 一句话概括容器&#xff1a;容器就是将软件打包成标准化单元&#xff0c;以用于开发、交付和部署。 容器镜像是轻量的、可执行的独立…

leetcode—跳跃游戏—贪心算法

1 跳跃游戏1 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&a…

Codeforces Round 922 (Div. 2)补题

Brick Wall&#xff08;Problem - A - Codeforces&#xff09; 题目大意&#xff1a;规定砖的大小为1*k&#xff08;k>2&#xff09;,现在有一面n*m的砖墙&#xff0c;n是墙高&#xff0c;m是墙宽&#xff0c;砖在砖墙中有两种放法&#xff0c;水平放置和竖直放置&#xff…

注册亚马逊店铺用动态IP可以吗?

注册亚马逊店铺可以用动态IP&#xff0c;只要是独立且干净的网线就没问题&#xff0c;亚马逊规则要求一个IP地址只能出现一个亚马逊店铺&#xff0c;若使用不当会导致关联账户。 固定ip可以给我们的账户带来更多的安全&#xff0c;要知道关联问题是亚马逊上的一个大问题&#…

《动手学深度学习(PyTorch版)》笔记4.8

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…

人工智能基础-Numpy.array基本操作

基本属性 查看维度 x.ndim查看维度&#xff08;元组形式&#xff09; x.shape元素个数 x.size数据访问 子矩阵 内容同步修改 加是copy&#xff08;&#xff09;则不同步修改 Reshape 修改维度 参数为-1时自动识别个数 合并 np.concatenate([x, y])沿着列合并 np.co…

第十四届蓝桥杯大赛软件赛省赛(C/C++ 大学B组)题解

尝试再做一次&#xff0c;我记得还是有点难&#xff0c;我会尽量多写一点解析&#xff0c;尽量让基础比较弱的友友也能看懂&#xff0c;希望能给你带来帮助 目录 1. 日期统计 题目描述 解题思路 具体代码 2. 01 串的熵 题目描述 解题思路 具体代码 3. 冶炼金属 题目…

如何编写具有完备性的测试用例 ? 具体思路是什么 ? 全套解决方案打包呈现给你 。

设计测试用例应该算是测试人员最为主要的工作之一 &#xff0c;好的测试用例往往具有覆盖性强 &#xff0c;扩展性高以及复用性好等特点 。该如何设计出好的测试用例 &#xff1f;是我们每一位测试人员需要重点思考的问题 &#xff0c;下面是我对设计测试用例设计的思考 &#…

#RAG|NLP|Jieba|PDF2WORD# pdf转word-换行问题

文档在生成PDF时,文宁都发生了什么。本文讲解了配置对象、resources对象和content对象的作用,以及字体、宇号、坐标、文本摆放等过程。同时,还解释了为什么PDF转word或转文字都是一行一行的以及为什么页眉页脚的问题会加大识别难度。最后提到了文本的编码和PDF中缺少文档结构标…