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

作业帮基于 Apache DolphinScheduler 3_0_0 的缺陷修复与优化

文|作业帮大数据团队(阮文俊、孙建业)

背 景

基于 Apache DolphinScheduler (以下简称DolphinScheduler)搭建的 UDA 任务调度平台有效支撑了公司的业务数据开发需求,处理着日均百万级别的任务量。

整个 UDA 的架构如下图所示,其中我们的引擎层主要基于 DolphinScheduler 的 Master 和 Worker 服务搭建,充分利用了 Master 节点优秀的高并发调度能力、worker 节点的分组隔离能力。我们通过一层适配层对 DolphinScheduler 对外暴露的接口进行了封装和增强来适配我们的业务场景。

图 1-1 UDA 任务调度平台架构

随着使用的深入,我们发现 DolphinScheduler3.0.0 版本中存在一些难以通过运维手段规避的问题,这些问题影响数据平台的稳定性,导致隔一段时间需要重启服务来使集群恢复正常,并且核心组件对外暴露的可观测性指标十分有限,导致问题的排查定位过程十分繁琐。我们认为一个可以稳定运行的调度引擎应该具备以下能力

  • 反压与过载保护机制:当系统负载比较高的时候,能够自动推迟任务执行,以保护自己。

  • 任务分配均衡:保证任务分配的均衡性,避免任务倾斜问题。

  • 无副作用运行:调度引擎在运行过程中不应对自身产生“副作用”,确保能够持续的长时间稳定运行。

  • 集群可观测性:具备全面的可观测性指标,能够通过这些指标评估集群的健康状态。

在这些能力上,开源版 3.0.0 的 Apache DolphinScheduler 尚存在一些问题,对此,我们进行了系列优化改造和修复,同时积累了丰富的运维经验。

优化实践

2.1 问题修复

2.1.1 HadoopUtils 引发的线程泄漏问题

在某次巡检的过程中,我们发现服务节点的线程数在过去一段时间呈明显的上升态势,根据经验判断,应该是程序中存在线程泄漏的地方,结合 metrics 发现泄漏速度为恒定速率,并且与任务并发量无关。

图 2-1 JVM 线程数不断增长

通过堆栈发现泄漏的线程主要是与 HDFS 相关,进一步将代码范围缩小至 HadoopUtils 之后,我们发现此处存在引发线程泄漏的代码逻辑。在 DS HadoopUtils 中存在一个 Cache,会以恒定的速率不断生成新的 HadoopUtils 实例,并放入 Cache,在 HadoopUtils 实例化的过程中会创建 HDFS FileSystem,但是却不会关闭原有的 FileSystem。

开源的 DS 在使用 HDFS FileSystem 时泄漏速度比较慢,不易发现。我们在生产环境中使用的是腾讯云提供的 CosFileSystem 插件,该插件中会使用多线程来加速文件的上传 / 下载操作。通过插件中的线程数目比对,与我们泄漏的线程数完全一致。

图 2-2 HadoopUtils 工作逻辑

至此,我们确定线程泄漏的原因是 HadoopUtils 在更新 Cache 的时候没有关闭 FileSystem,于是我们在更新 Cache 的时候关闭 FileSystem,并通过读写锁保证不会由于异步关闭导致文件操作失败,成功的解决了线程泄漏的问题。对比上线前后的 JVM 线程指标,修复之后线程数保持在一个小恒定范围内。

图 2-3 修复前后 JVM 线程数对比

2.1.2 TaskExecuteRunnable 内存泄漏引发 CPU 飙高问题

在生产环境中,我们发现在任务量没有发生明显变化时,Master 服务随着运行时间越长,其 CPU 使用率出现增长趋势。

图 2-4 Master 服务 CPU 使用率不断增长

通过分析火焰图,我们发现 Master 中存在一处代码逻辑,随着程序的运行时间越久,这段代码逻辑对 CPU 的消耗会越来越高。

图 2-5 任务事件处理器 CPU 使用占比很高

通过梳理代码逻辑,我们发现 DolphinScheduler 的 Master 服务在运行工作流时采用事件驱动的方式,每个任务实例在运行过程中会生成一个对应的 TaskExecuteRunnable 对象,任务在运行过程中产生的生命周期事件会存放在 TaskExecuteRunnable 对象中。会有一个后台线程轮询当前服务中存活的 TaskExecuteRunnable 对象,然后提交事件处理任务到事件线程池。

不过,当任务运行结束之后,TaskExecuteRunnable 并不会被释放,还会存放在任务事件线程池中,这就会导致任务事件处理线程空转时间越来越长。

通过分析堆栈,我们的判断得到了验证,TaskExecuteRunnable 的确会泄漏,不过由于 TaskExecuteRunnable 占用内存很少,因此很难从内存中反应出来。我们的集群中有 4 台 Master,任务实例数一天百万左右,因此对于单台 Master 一天会泄漏大约 25w TaskExecuteRunnable,随着时间的积累会拖慢引擎的事件处理。

图 2-6 Master 堆内存 TaskExecuteRunnable 对象泄漏

于是我们进行了代码修复,在任务执行结束之后,移除内存中的 TaskExecuteRunnable 对象。对比修复前后的 JVM CPU 指标,修复之后,Master 的 CPU 指标随着运行时间始终维持在一个小的恒定范围内。

图 2-7 修复前后 Master 服务 CPU 使用变化

2.1.3 Master 执行逻辑任务重复提交事件,导致事件堆积问题

DolphinScheduler 中任务分为两类,分别为以 dependent 为代表的逻辑任务和以 Shell 为代表带的物理任务,其中逻辑任务在 Master 中执行,物理任务在 Worker 中执行。不管是逻辑任务还是物理任务在 Master 处理过程中都会经历以下阶段。

图 2-8 Master 中任务处理流程

逻辑任务和物理任务的区别在于 Dispatch 和 Run 阶段的实现不同,对于逻辑任务不需要触发真正的 Dispatch,Run 阶段运行在 Master 中。而物理任务在 Dispatch 阶段会将任务分发给 Worker,Run 阶段运行在 Worker 中。

无论是哪种任务,当 Dispatch 阶段执行成功之后,会注册到 StateWheelThread 中,该组件会定时的每隔 5 秒钟为每个任务生成一个 TaskStateChangeEvent,提交到任务的事件队列中,TaskStateChangeEvent 被处理的时候会触发 Run 任务,对于逻辑任务会不断的通过 TaskStateChangeEvent 触发执行。

图 2-9 StateWheelThread 生产消费模型

这里是一个典型的生产消费模型,生产者以固定的速率(每隔 5 秒)生成事件写入队列,消费者异步的从队列中消费事件。

因此当消费者处理的速度小于生产者生产的速度时,这里就会出现事件堆积。

而实际情况下,由于生产者生产事件的时候是纯内存计算,没有任何 io 阻塞,而消费者处理事件的时候需要多次查询 db。对于 Dependent 这类逻辑任务的运行时间通常都很长,因此如果达到一定的并发量,这里极大概率会出现事件积压,导致整个 master 中所有任务的状态事件处理出现延迟、增加数据库压力,严重的话还会导致 Master OOM 服务宕机。

在我们的测试环境中,单台 Master 服务,事件线程池大小为 100,Dependent 并发数超过 500,此时就 Master 中的 StateEvent 就会出现堆积的情况。

图 2-10 修复前 StateEvent 变化情况

我们发现堆积的事件都是用来触发逻辑任务 Run 阶段,并且对于同一任务实例存在多个重复的触发事件,我们通过对事件去重从而修复堆积的情况。在修复之后,事件的堆积情况得到解决,一旦事件的消费速度低于增长速度,事件的堆积量最多为任务的并发数,不会出现一直积累的情况。

图 2-11 修复后 StateEvent 变化情况

2.1.4 Master 任务调度不均匀

Master 在分配任务给 Worker 的时候,会使用负载均衡策略,使任务的分配尽量均衡。默认的均衡策略是 LOW_WEIGHT,该策略会通过 Worker 的心跳信息来计算一个负载量,会将任务分配给负载量最低的 worker。

图 2-12 Worker 通过 Heartbeat 暴露自身负载情况

在实际的使用过程中我们发现在大多数情况下,这种负载策略会出现严重的任务分配不均衡的情况,在同一个 WorkerGroup 下,不同的 Worker 被分配到的任务量可能会相差几十倍。

图 2-13 Worker 任务分配失衡

究其原因我们发现主要是由两个方面导致

  • 负载计算的值无法代表负载情况

在计算 Worker 节点的负载时,Master 会对 Worker 的 CPU、内存、Load、等待任务数分别加一个权重来做归一化,但是针对各资源加权值和归一化算法表达不严谨。导致计算出来的负载值实际上并不能正确的反应 Worker 的真实负载情况,并且实际生产很难通过调节权重得到一个真实的值。

  • 负载计算不是实时的

Worker 的心跳上报是定时上报,Master 在分发任务时使用的 Worker 心跳数据并不能反映当前 Worker 的真实情况,这会导致某个时刻一旦出现一个负载量偏低的 worker,master 在接下来一段时间中可能会将大量的任务都发送给这台 worker,从而导致任务倾斜。

分析完原因之后,我们决定使用 RANDOM 策略来分发任务,保证 Master 在分发时绝对均衡,然后由 Worker 自己通过自身负载决定是否要接受 Master 的分发请求。对比修复前后同一个 worker 分组下不同 Pod 接收的任务,发现修复后不同的 pod 接收的任务变得均衡,不再出现任务倾斜的情况。

图 2-14 修复前后 Worker 接收任务对比

2.1.5 Master 事件处理卡住问题

在生产环境中,我们发现 Master 的 CPU 持续升高,通过服务日志发现 Master 一直在处理某个事件,并且伴随异常,我们猜测此时出现了事件死循环的情况。通过研究 DolphinScheduler3.0.0 中 Master 事件驱动流程我们发现在该版本中存在三类事件。

  • WorkflowStartEvent

WorkflowStartEvent 是工作流启动事件,该事件是由一个单独的后台线程产生,并且由一个单独的后台线程处理,用于启动工作流,工作流的元数据出现异常时会导致 WorkflowStartEvent 执行出现异常,此时异常的 WorkflowStartEvent 会一直重试并阻塞后面其他事件,直到在数据库中对元数据进行修复。

图 2-15 WorkflowStartEvent 处理流程

  • StateEvent

StateEvent 是工作流和任务执行相关的事件,用于驱动 DAG 拓扑执行。

StateEvent 有以下事件类型:工作流状态变更、任务状态变更、工作流超时、任务超时、TaskGroup 中的任务被唤醒、任务重试、工作流阻塞。

对于一个工作流来说,里面所有的 StateEvent 都存储在一个队列中,事件按照进入队列的先后顺序被执行。并且采用的是 DFS 的方式被线程池消费,即一个队列被 fire 的时候会被分配给一个线程,该线程直到处理完队列中的所有事件才会退出,如果一旦有某个队列在处理时无法退出,那么线程会被一直占用。

图 2-16 StateEvent 处理流程

  • TaskEvent

当任务实例在运行时发生了变化会生成 TaskEvent,即该事件是由 Worker 发送的任务数据所转换而来,以下情况都会生成 TaskEvent,TaskEvent 处理流程和 StateEvent 类似。

  • 任务实例被分发成功了,那么会触发 Dispatch 类型的 TaskEvent。

  • 任务实例延迟执行了,那么会触发 Delay 类型的 TaskEvent

  • 任务实例开始运行了,那么会触发 Running 的 TaskEvent

  • 任务实例运行结束了,会触发 Result 类型的 TaskEvent

值得注意的是以上三种事件都采用死信队列的方式存放,即只有当事件被处理成功才会将事件从队列移除,社区最初这么设计是希望在某些情况下由于基础设施故障,例如 db 抖动等不会影响到事件的处理,但实际上有很多其他的意外情况会导致事件处理失败,例如数据库存在非正常数据,事件发送过程中出现乱序等。

我们认为对于引擎来说,需要避免由于某一个工作流事件处理出现问题,从而影响到引擎的稳定性。因此,我们移除了这里的死信队列,当事件处理失败的时候,会直接抛弃事件,并将工作流快速置为失败,由上层进行重试,并结合 Metrics 监控各类事件的处理情况。修复后,Master CPU 保持稳定,服务日志也不再出现一直重复处理某个事件。

图 2-17 三种事件监控情况

2.2 稳定性优化

2.2.1 工作流实例健康检查

目前 DolphinScheduler 中 Master 执行工作流的时候会将工作流实例的元数据存储在内存,然后通过事件驱动的方式去进行状态流转,直至工作流中所有的任务都结束然后将工作流实例从内存卸载。在某些情况,例如网络原因导致事件丢失,或者事件在处理过程中由于状态机 bug 处理失败从而丢失,此时会导致工作流实例处理流程卡住,从而导致工作流实例成为孤儿实例,即永远不可能结束。

此时如果发现了可以在上层通过 kill 的方式去停止工作流实例,从而卸载,不过这种方式存在两个问题。一是依赖业务方自行检测,需要业务方定期的巡检整个系统,当业务方发现问题时往往业务已经受到了影响。二是处理的方式很繁琐,一旦运行的工作流实例数比较多的时候,逐个操作成本比较高。我们希望调度引擎能够有自检功能,能够自己检测工作流实例是否已经变成僵尸实例,并且自动上报,自动做恢复操作。

对此,我们进行了优化,在 Master 中添加一个组件 WorkflowInstanceHealthCoordinator,该组件用于定期对当前 Master 运行中的每个工作流实例执行健康检查。在健康检查的时候会通过 HeartbeatEmitter 去触发工作流实例的心跳检测,当连续多次的心跳检测失败之后,会通过 DeadWorkflowInstanceHandler 去清除该工作流实例,并上报 metrics。

图 2-18 健康检查流程

整个检测主要是由 WorkflowInstanceHealthCoordinator 负责,该组件在每个 Master 中采用单例的形式,里面包含一个后台线程,和 EventExecuteService 工作模式类似,当一个工作流实例被加载到 Cache 之后,会同时在 WorkflowInstanceHealthCoordinator 中注册自己,当工作流实例执行结束从 Cache 中移除的时候也会同步从 WorkflowInstanceHealthCoordinator 移除。

图 2-19 WorkflowInstanceHealthCoordinator 处理流程

WorkflowInstanceHealthCoordinator 中有一个后台线程会定期的(默认 5min 一次,可自定义配置检测间隔)对注册进来的工作流实例做健康检查。

健康检查的方式是通过对工作流实例中所有未结束的任务做心跳探测,如果探测成功,则表明该工作流实例是存活的,如果探测失败,则表明该工作流实例可能已经出现了异常。对一个工作流实例如果探测失败的次数超过了阈值,我们认为该工作流实例已经成为僵尸工作流实例,我们目前会进行告警,由运维同学介入,当前我们尚未实现自动故障恢复,因为此类僵尸实例发生的情况不会很多,后续我们会考虑实现对僵尸实例自动运维。

2.2.1 Worker 中任务事件 TTL

DolphinScheduler 中 Worker 主要职责是接受任务,执行任务,上报任务事件。

其中任务事件在上报的时候存放在内存中的一个死信队列中。


图 2-20 Worker 上报任务事件流程

整个过程为

  • 任务执行过程中生成任务事件,并将事件提交到死信队列,每个任务会有一个单独的死信队列

  • Worker 中有一个后台线程会定期轮询死信队列,当事件达到重试间隔之后会重新发送事件给 master

  • Master 在处理完事件之后会发送对应事件 ACK 给 worker,worker 收到 ACK 之后会清除事件,当死信队列中所有事件都为空,并且任务执行结束,此时会卸载死信队列。

这样做的好处是能够避免因为网络抖动或者 master 因为故障而导致某段时间内事件上报不成功从而丢失事件,不过这样也会导致可能出现内存泄漏的问题。例如,如果 master 发生容错,那么会进行工作流容错,容错的时候会先 kill 任务,然后重新提交,在 kill 的时候如果发送 RPC 给 worker 失败了,此时 worker 中的任务事件将永远不会被清除,并且由于工作流实例发生了容错,此时某些任务事件可能无法发送给容错后的 master,即会一直重试,变成僵尸消息。

即一旦消息的目的地发生了变化,但是 worker 感知不到,那么会导致消息泄漏到内存。

一旦发生泄漏,可能会导致重试线程中堆积大量的无效事件,这会占用线程资源,导致有效事件发送出现延迟,并且这类无效事件永远不会被释放,会造成内存泄漏,影响服务稳定性。

对此,我们在事件中添加了 TTL,每个事件在创建的时候会带有 createTime,如果 currentTime-createTime>ttl,那么表明事件在给定的时间内没有发送成功,此时说明事件可能已经出现了泄漏,会在 prometheus 中打点,并自动从死信队列队列中清除。

图 2-21 事件添加 TTL 检测

2.2.2 历史数据保留策略

随着系统使用时间的增长,数据库和磁盘数据逐渐积累,会影响服务运行和数据库稳定性。实际运维中我们发现,数据库中增长的主要是一些实例元数据,这些数据的积累会导致数据库压力越来越大,同时会伴随慢查询越来越多。磁盘中增长的主要是任务实例日志和任务实例工作目录,这些数据的积累会导致磁盘可用容量和 inode 变得越来越少。

我们希望程序能够自动的清理无用的历史数据。例如,在数据库中仅保留最近一个月的运行实例数据。磁盘上保留最近一周的临时文件,超出保留期限的数据则自动删除,以减少人工运维的工作。

由于 DolphinScheduler 原生的删除接口在做数据清理的时候是按照工作流实例的维度,即清理历史数据的时候需要先找出工作流实例下的任务实例,然后分别清理每个任务实例的数据,这个过程涉及大量的数据库操作和 RPC 操作,并且执行批量删除操作的时候会给服务带来很大的压力,不适用大批量数据的清理。为此,我们分别在 Master 和 Worker 中添加了 InstanceDBPurgerThread 和 TaskFilePurgerThread 两个后台线程组件,分别负责数据库实例数据和磁盘文件的定期检查、上报与清除工作。

数据库方面主要清理工作流实例、任务实例和告警事件等数据。磁盘方面,主要是清理 exec 目录下的临时文件夹,log 目录下的任务实例日志等数据。同时,通过暴露相关的 metrics 对这些数据量进行监控。将数据库和磁盘的清理分开可以极大的加速历史数据的清除速度。

图 2-21 实例变化情况

2.3 巡检流程

为了确保系统稳定运行,我们不仅配置了大量告警,还定期进行日常、周、月巡检。通过巡检,我们能够提前发现潜在问题,不断的完善自动化运维流程。我们目前发现的大多数问题都是通过巡检提前发现,避免了对业务造成实际影响。

同时,巡检也帮助我们不断优化我们的监控大盘和告警项。目前我们从集群、项目、WorkerGroup 和 Pod 等维度搭建了监控面板和告警,以辅助巡检工作。

图 2-22 不同维度的监控面板

图 2-23 Cluster 维度部分面板

图 2-24 项目维度部分面板

图 2-25 WorkerGroup 维度部分面板

在日常巡检中,我们主要关注集群、项目、WorkerGroup 三个维度下的指标。在集群维度上,关注 Master Slot 变化、集群水位、并发量、资源使用等稳定性指标。在项目和 WorkerGroup 维度,关注异常任务、任务量的同比变化,WorkerGroup 下 Slot 使用率及业务运行情况。Pod 维度则用于周巡检和问题排查。

未来规划

目前 DolphinScheduler3.0.0 已经在我们的生产环境中稳定运行,我们针对使用场景中发现的问题,在不进行大规模架构调整的前提下做出了修复和优化,并且沉淀出了一套适用于当前业务场景的运维手段。社区在后续版本中对某些问题进行了更完善的修复,如针对逻辑任务事件阻塞的问题,重构了整个逻辑任务执行流程;针对状态机卡住问题,重构了状态机模型等。未来,随着业务量和使用场景的扩展,我们会考虑版本升级到 3.2+ 版本,以尽可能与社区保持同步,并将我们所做的一些优化项反馈至社区。

本文由 白鲸开源科技 提供发布支持!

相关文章:

作业帮基于 Apache DolphinScheduler 3_0_0 的缺陷修复与优化

文|作业帮大数据团队(阮文俊、孙建业) 背 景 基于 Apache DolphinScheduler (以下简称DolphinScheduler)搭建的 UDA 任务调度平台有效支撑了公司的业务数据开发需求,处理着日均百万级别的任务量。 整个 UDA 的架构如…...

【LC】111. 二叉树的最小深度

题目描述: 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:2示…...

HarmonyOS NEXT 实战之元服务:静态案例效果--- 歌手推荐

背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图1完整代码案例如下: import { authentication } …...

selenium自动化测试(超详细~)

最近也有很多人私下问我,selenium学习难吗,基础入门的学习内容很多是3以前的版本资料,对于有基础的人来说,3到4的差别虽然有,但是不足以影响自己,但是对于没有学过的人来说,通过资料再到自己写的…...

Spring Boot教程之三十一:入门 Web

Spring Boot – 入门 Web 如今,大多数应用程序都需要模型-视图-控制器(MVC) 架构来满足各种需求,例如处理用户数据、提高应用程序效率、为应用程序提供动态特性。它主要用于构建桌面图形用户界面 (GUI),但现在越来越流行用于构建基于 Web 的…...

【每日学点鸿蒙知识】指纹识别隐藏背面、数组内部值变化刷新UI、键盘输入类型、跨组件路由、C++20特性支持

1、HarmonyOS 指纹识别情况下,隐藏背面内容? 有一个场景,在指纹识别验证页面时候,此时需要用户看不到背面的内容,请问应该怎么处理这块。或者有什么方案,可以通过window,获取到当前页面的page&…...

Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息

目录 Python正则表达式re库的基本用法 引入re库 各函数功能 总结 使用方法举例 正则表达式语法与书写方式 正则表达式的常用操作符 思科ASA防火墙数据 数据1 数据2 书写正则表达式 Python中pydantic的使用 导入基础数据模板 根据数据采集目标定义Pydantic数据类型…...

centos系统如何安装kubectl和部署kube-apiserver

1.使用 yum 安装&#xff08;推荐&#xff09; 添加 Kubernetes 软件源&#xff1a; 首先&#xff0c;你需要添加 Kubernetes 的官方 YUM 软件源。这可以通过下载并安装 kubernetes.repo 文件来实现。 shell cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [k…...

【源码编译】windows下mingw64安装以及cmake调用

最近因为安装MIRTK库&#xff0c;太多第三方依赖了&#xff0c;太折磨了&#xff0c;学习了使用Cmake&#xff0c;有些库又需要Fortran编译器&#xff0c;VS2022里面装了但又调用不了&#xff0c;也不知道为什么&#xff0c;最后装的mingw64&#xff0c;记录一下。 1、mingw64安…...

HarmonyOS NEXT 实战之元服务:静态案例效果---最近播放音乐

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; Index import { authentica…...

【QT开发自制小工具】PDF/图片转excel---调用百度OCR API接口

前言 前几年WPS还可以免费处理5页以内的PDF转excel&#xff0c;现在必须付费了&#xff0c;而且百度其他在线的PDF转excel都是要收费的&#xff0c;刚好前几年调研过百度OCR的高精度含位置接口&#xff0c;依然是每天可以免费调用50次&#xff0c;本篇是基于此接口&#xff0c;…...

uniapp 基于xgplayer(西瓜视频) + renderjs开发,实现APP视频播放

背景&#xff1a;在uniapp中因原生video组件功能有限&#xff0c;选择引入xgplayer库来展示视频播放等功能。并且APP端无法操作dom&#xff0c;所以使用了renderjs。 其他的不多说&#xff0c;主要列举一下renderjs中需要注意的点&#xff1a; 1、使用&#xff1a;在标签后&…...

[1111].集成开发工具Pycharm安装与使用

所有博客大纲 后端学习大纲 Python大纲 1.下载&#xff1a; 官方下载地址 2.安装&#xff1a; 1.双击exe文件&#xff0c;然后下一步选择安装目录 2.选择桌面快捷方式及安装&#xff1a; 3.安装完成 3.启动&#xff1a; 4.设置&#xff1a; 4.1.设置运行时环境&#xff1a;…...

【玩转OCR】 | 腾讯云智能结构化OCR在多场景的实际应用与体验

文章目录 引言产品简介产品功能产品优势 API调用与场景实践图像增强API调用实例发票API调用实例其他场景 结语相关链接 引言 在数字化信息处理的时代&#xff0c;如何高效、精准地提取和结构化各类文档数据成为了企业和政府部门的重要需求。尤其是在面对海量票据、证件、表单和…...

红狮金业:2024年尾声,黄金市场需要关注的消息面

随着2024年的尾声渐近&#xff0c;全球金融市场在美联储的年度最后一次降息决策中迎来了新的波澜。上周&#xff0c;美联储宣布降息&#xff0c;而美联储主席鲍威尔随后的发言更是在市场上掀起了巨大波动。他透露&#xff0c;美联储计划在明年放缓降息步伐&#xff0c;可能仅实…...

使用BCrypt进行密码加密

1. 添加依赖&#xff1a; 在pom.xml文件中添加Spring Security依赖&#xff0c;以使用BCryptPasswordEncoder。 <!-- Spring Security 依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-secu…...

《智启新材热学性能优化之路:人工智能的神奇力量》

在当今科技飞速发展的时代&#xff0c;材料科学与人工智能的融合正成为创新的前沿阵地。其中&#xff0c;利用人工智能优化材料的热学性能&#xff0c;为众多领域的突破带来了新的曙光&#xff0c;从航空航天的高效热防护到电子设备的散热管理&#xff0c;其影响深远且广泛&…...

IIC驱动EEPROM

代码参考正点原子 i2c_dri:主要是三段式状态机的编写 module iic_dri#(parameter SLAVE_ADDR 7b1010000 , //EEPROM从机地址parameter CLK_FREQ 26d50_000_000, //模块输入的时钟频率parameter I2C_FREQ 18d250_000 //IIC_SCL的时钟频率)( …...

目标检测——基于yolov8和pyqt的螺栓松动检测系统

目录 1.项目克隆和环境配置1.1 我这里使用的是v8.0.6版本1.2 项目代码结构介绍 2.数据集介绍2.1 数据集采集2.2采集结果介绍 3.模型训练4.pyqt界面设计4.1 界面内容介绍4.2 界面实现 5.操作中的逻辑实现5.1 图片检测5.2 文件夹检测5.3 视频检测和摄像头检测 6. 效果展示 1.项目…...

JVM系列(十三) -常用调优工具介绍

最近对 JVM 技术知识进行了重新整理&#xff0c;再次献上 JVM系列文章合集索引&#xff0c;感兴趣的小伙伴可以直接点击如下地址快速阅读。 JVM系列(一) -什么是虚拟机JVM系列(二) -类的加载过程JVM系列(三) -内存布局详解JVM系列(四) -对象的创建过程JVM系列(五) -对象的内存分…...

酷睿i7和i5哪个好?i5和i7的区别介绍

在英特尔酷睿处理器家族中&#xff0c;i7与i5作为面向不同用户群体的主流产品&#xff0c;各自承载着不同的性能定位与使用价值。在面对“酷睿i7和i5哪个好”的问题时&#xff0c;答案并非一概而论&#xff0c;而是取决于具体的应用需求、预算考量以及对性能与效率的期待。本文…...

实现用户登录系统的前后端开发

**一、**实验名称 实现用户登录系统的前后端开发。 **二、**参考资料 Web开发技术第一章课件。 **三、**实验目的 1.练习前端基本技术的使用。 2.练习使用Servlet/JSP开发简单后端程序。 3.练习使用Tomcat发布Web应用。 4.练习使用Spring Boot开发简单的后端程序。 **…...

Log4j1.27配置日志输出级别不起效

起因&#xff1a;构建独立版本debezuim使用时&#xff0c;日志一直打印debug信息。 原因&#xff1a;包冲突问题&#xff0c;进行排包操作。 参考log4j日志级别配置完成后不生效 系统一直打印debug日志_log4j不起作用-CSDN博客 1、application.properties logging.configc…...

一、后端到摄像头(监控摄像头IOT)

前言&#xff1a; 开发流程从 后端到摄像头 打通是第一步&#xff0c;那么我们可以着手设计 后端实现 的具体步骤&#xff0c;确保能够稳定地接收和处理来自摄像头的视频流&#xff0c;并提供后续的功能扩展&#xff0c;如视频流转发、存储和控制。 1. 后端系统架构设计 在开始…...

H3C MPLS跨域optionB

实验拓扑 实验需求 如图,VPN1 和 VPN2 分别通过运营商 MPLS VPN 连接各自分支机构按照图示配置 IP 地址,VPN1 和 VPN2 连接同一个 PE 设备的私网 IP 网段存在地址复用,使用多 VRF 技术来防止 IP 冲突AS 100 和 AS 200 内部的公共网络中各自运行 OSPF 使 AS 内各设备的 Loo…...

微信小程序中momentjs无法切换中文问题处理

微信小程序中momentj.s无法切换中文问题处理. 表现为 使用 locale(“zh-cn”)无效。 处理方法 # 1、先删除 miniprogram_npm\moment\index.js # 2、将 node_modules\moment\min\moment-with-locales.min.js 复制到 miniprogram_npm\moment下 并重命名为index.js # 3、修改mi…...

Linux零基础速成篇一(理论+实操)

前言&#xff1a;本教程适合Linux零基础学习&#xff0c;也适合Linux期末考试的小伙伴&#xff0c;从头到尾理论与实操相结合&#xff0c;让你快速对Linux进行了解和掌握。 一、Linux概述 为什么要学习Linux操作系统&#xff1f; 完全免费-开源 任何用户均可下载使用 安全…...

【087】基于51单片机智能宠物喂食器【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统LCD1602液晶显示MY1680语音播放模块DS1302时钟芯片SG90舵机AT24C02存储芯片LED灯按键设置。 1、设计采用STC89C52、AT89C52、AT89S52作为主控芯片&#xff1b; 2、系统采用DS1302时钟芯片实现对日期时间计时并通过LCD1602液晶显…...

全局流量管理:提升用户体验与保障服务稳定性

全局流量管理的工作原理 全局流量管理主要依赖于 DNS&#xff08;域名系统&#xff09;技术&#xff0c;通过将全球用户的访问请求引导至离他们最近的服务器或数据中心&#xff0c;极大减少了访问延迟和带宽负载&#xff0c;从而提升了用户体验。同时&#xff0c;GTM 还结合健…...

达梦数据守护搭建

主备库初始化 ./dminit path/dmdata/data db_nameDM01 instance_nameDMSVR01 port_num5236 page_size16 extent_size32 log_size500 case_sensitive1 SYSDBA_PWDDM01SYSDBA ./dminit path/dmdata/data db_nameDM02 instance_nameDMSVR02 port_num5236 page_size16 extent_size3…...

【C++】容器适配器全知道

亲爱的读者朋友们&#x1f603;&#xff0c;此文开启知识盛宴与思想碰撞&#x1f389;。 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 目录 一、前言 二、什么是适配器 &#xff08;一&#xff09;现实生…...

企业资源规划系统(ERP)服务器上线项目实施指南

企业资源规划系统&#xff08;ERP&#xff09;服务器上线项目实施指南 项目背景 在当今竞争激烈的商业环境中&#xff0c;企业资源规划系统&#xff08;ERP&#xff09;已成为企业提升内部管理效率和响应市场变化的重要工具。为了实现业务流程的整合和优化&#xff0c;公司决…...

Kubernetes(k8s)离线部署DolphinScheduler3.2.2

1.环境准备 1.1 集群规划 本次安装环境为&#xff1a;3台k8s现有的postgreSql数据库zookeeper服务 1.2 下载及介绍 DolphinScheduler-3.2.2官网&#xff1a;https://dolphinscheduler.apache.org/zh-cn/docs/3.2.2 官网安装文档&#xff1a;https://dolphinscheduler.apach…...

嵌入式linux驱动框架 从0到1编写设备驱动 i2c_driver i2c_client

一、编写最简单的IIC驱动框架 在之前的文章中&#xff0c;我们已经深入探讨了I2C通信的基本原理、硬件架构以及时序等基础知识。现在&#xff0c;我们将进入一个更加实际和深入的层面&#xff0c;构建一个完整的I2C驱动程序&#xff0c;并阐述驱动框架的设计。这将帮助你不仅能…...

小程序canvas画环形百分比进度图

组件封装 component/canvas-ring目录下 canvas-ring.js <canvas style"width:{{canvasWidth}}px;height:{{canvasWidth}}px; margin:0 auto;position:relative" type"2d" id"myCanvas"><view class"circle-bar" style&quo…...

面试经验分享 | 北京渗透测试岗位

更多大厂面试经验的视频经验分享看主页 目录&#xff1a; 所面试的公司&#xff1a;安全大厂 所在城市&#xff1a;北京 面试职位&#xff1a;渗透测试工程师 面试方式&#xff1a;腾讯会议线上面试线下面试 面试过程&#xff1a; 面试官的问题&#xff1a; 1、说一下XSS有哪…...

安卓 SystemServer 启动流程

目录 引言 Android系统服务启动顺序 zygote fork SystemServer 进程 SystemServer启动流程 1、SystemServer.main() 2、SystemServer.run() 3、初始化系统上下文 4、创建系统服务管理 5、启动系统各种服务 总结 引言 开机启动时 PowerManagerService 调用 AudioSer…...

opencv存图速度测试

以下测试的图片&#xff0c;均为5488x3672分辨率的三通道彩色图。 分别使用opencv和halcon存图&#xff0c;测试速度&#xff0c;存100次取平均值&#xff0c;结果如下&#xff1a; image size:5488 3672 opencv jpg save time 0.12809s opencv bmp save time 0.02197s hal…...

[ffmpeg]编译 libx264

步骤 下载 libx264 git clone https://code.videolan.org/videolan/x264.git cd x264环境搭建 然后在开始菜单中找到并打开 x64 Native Tools Command Prompt for VS 2019 &#xff1a; 打开 msys2_shell.cmd -use-full-path 这时会打开 MSYS 的新窗口&#xff0c;先把一些汇…...

常见API

1.API 1.1API概述 什么是API ​ API (Application Programming Interface) &#xff1a;应用程序编程接口 java中的API ​ 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要…...

vscode写python,遇到问题:ModuleNotFoundError: No module named ‘pillow‘(已解决 避坑)

1 问题&#xff1a; ModuleNotFoundError: No module named pillow 2 原因&#xff1a; 原因1&#xff1a;安装Pillow的pip命令所处的python版本与vscode调用的python解释器版本不同。 如&#xff1a; 原因2&#xff1a;虽然用的是pillow&#xff0c;但是写代码的时候只能用…...

【mysql】id主键列乱了之后,重新排序(可根据日期顺序)

一、ID中断不连续的&#xff0c;重新设置为连续的ID alter table table_name drop id; alter table table_name add id int not null first; alter table table_name modify column id int not null auto_increment, add primary key(id); select * from table_name order by …...

SO-CNN-LSTM-MATT蛇群算法优化注意力机制深度学习多特征分类预测

SO-CNN-LSTM-MATT蛇群算法优化注意力机制深度学习多特征分类预测&#xff08;多输入单输出&#xff09; 目录 SO-CNN-LSTM-MATT蛇群算法优化注意力机制深度学习多特征分类预测&#xff08;多输入单输出&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matl…...

原点安全再次入选信通院 2024 大数据“星河”案例

近日&#xff0c;中国信息通信研究院和中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同组织开展的 2024 大数据“星河&#xff08;Galaxy&#xff09;”案例征集活动结果正式公布。由工银瑞信基金管理有限公司、北京原点数安科技有限公司联…...

Hadoop

HDFS一键启动/停止 start-dfs.sh stop-dfs.sh 单进程启动/停止 $HADOOP_HOME/bin/hdfs&#xff0c;此程序也可以用以单独控制所在机器的进程的启停 hdfs --daemon (start|status|stop) (namenode|secondarynamenode|datanode)#例如启动namenode&#xff0c;去到需要启动的服…...

【Ambari】使用 Knox 进行 LDAP 身份认证

目录 一、knox介绍 二、Ambari配置LDAP认证 三、验证Knox网关 3.1YARNUI 3.2 HDFSUI 3.3 HDFS RestFULL 3.4 SparkHistoryserver 3.5 HBASEUI 一、knox介绍 Apache Knox网关是一个用于与Apache Hadoop部署的REST api和ui交互的应用程序网关。Knox网关为所有与Apache Ha…...

计算机网络习题( 第3章 物理层 第4章 数据链路层 )

第3章 物理层 一、单选题 1、下列选项中&#xff0c;不属于物理层接口规范定义范畴的是&#xff08; &#xff09;。 A、 接口形状 B、 引脚功能 C、 传输媒体 D、 信号电平 正确答案&#xff1a; C 2、在物理层接口特性中&#xff0c;用于描述完成每种功能的事件发…...

Windows系统中mt6.dll文件缺失是什么原因?mt6.dll文件缺失详解与修复指南

mt6.dll文件的作用 mt6.dll是一个动态链接库文件&#xff0c;它通常与特定的软件或游戏相关联&#xff0c;用于支持这些程序中的某些功能。虽然它并非Windows系统的核心文件&#xff0c;但对于依赖于它的程序来说&#xff0c;mt6.dll的缺失可能导致程序无法正常运行或启动。 …...

homebrew,gem,cocoapod 换源,以及安装依赖

安装homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 再按照成功提示配置环境变量 ruby 更新ruby到最新 brew install ruby 如果安装了会自动升级 安装完成后根据提示配置环境变量 再执行命令使其生效 s…...

uni-app开发商品详情页面实现

目录 一:功能描述 二:功能实现 一:功能描述 商品详情页主要展示商品的图片,基础信息,详细描述信息,以及销量,库存信息等。 首先在顶部以轮播图形式展示图片信息,下面展示商品价格和商品名称和描述信息,然后显示商品的关键卖点信息,最后展示商品详情信息。 二:功…...