利用Quartz实现复杂的任务调度

第一章:引言

大家好,我是小黑,任务调度,简而言之,就是按照预定计划自动执行任务的过程。不管是数据库备份、报表生成还是发送定时邮件,它们都需要一个可靠的任务调度系统来保证按时完成。

那么,为什么小黑要选择Quartz这个框架来实现复杂的任务调度呢?原因有很多,但最吸引人的莫过于它的灵活性和强大功能。Quartz不仅支持简单的到复杂的cron表达式,还能在运行时动态调整任务计划,这对于需要高度灵活性的项目来说是非常重要的。

第二章:Quartz基础

Quartz是一个开源的作业调度库,可以集成到几乎任何Java应用中。在深入了解Quartz之前,咱们先来看看它的几个基本概念:作业(Job)、触发器(Trigger)和调度器(Scheduler)。

  • 作业(Job):这是咱们想要调度的任务,就是咱们要执行的具体逻辑。
  • 触发器(Trigger):定义了作业执行的时间规则。在Quartz中,最常用的触发器是SimpleTrigger和CronTrigger。
  • 调度器(Scheduler):调度器就像一个容器,它负责容纳作业和触发器,并按照触发器定义的规则执行作业。

现在,小黑来展示如何使用Quartz创建一个简单的任务调度。首先,咱们需要添加Quartz的依赖到项目中。使用Maven的话,就是在pom.xml文件中加入以下依赖:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version> <!-- 请根据实际情况选择合适的版本 -->
</dependency>

小黑偷偷告诉你一个买会员便宜的网站: 小黑整的视頻会园优惠站

第三章:Hello Quartz

在前两章,咱们了解了任务调度的概念以及Quartz的基本构成。现在,小黑将带领咱们通过一个简单的示例,深入了解如何使用Quartz实现任务调度。这个示例将会是一个经典的“Hello, Quartz!”程序,通过它,咱们可以看到Quartz在实际操作中是如何工作的。

咱们已经创建了一个HelloJob类,它实现了Job接口,并覆盖了execute方法。这个方法里的逻辑会在任务触发时执行。下面,小黑要展示的是如何创建一个调度器(Scheduler),以及如何定义触发器(Trigger)来按计划执行咱们的HelloJob

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class HelloQuartz {
    public static void main(String[] args) {
        try {
            // 创建调度器
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 启动调度器
            scheduler.start();

            // 定义一个作业,并将其与HelloJob类绑定
            JobDetail job = JobBuilder.newJob(HelloJob.class)
                    .withIdentity("job1", "group1")
                    .build();

            // 创建一个触发器,立即执行,然后每2秒重复一次
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(2)
                            .repeatForever())
                    .build();

            // 告诉调度器使用触发器来安排作业
            scheduler.scheduleJob(job, trigger);

            // 让调度器运行一段时间后关闭
            Thread.sleep(10000);
            scheduler.shutdown();

        } catch (SchedulerException | InterruptedException se) {
            se.printStackTrace();
        }
    }
}

在这段代码中,咱们首先通过StdSchedulerFactory.getDefaultScheduler()获取一个调度器实例,并通过调用start()方法启动它。接着,创建一个JobDetail实例,这里指定了作业的类为HelloJob,并给这个作业以及所属的组分配了一个唯一标识符。紧接着,定义了一个触发器,这个触发器配置了作业的执行计划:从当前时刻开始,每隔2秒执行一次,且无限重复。

通过调用scheduleJob方法,咱们将作业和触发器注册到调度器中,这样Quartz就会根据触发器定义的规则来执行作业了。为了能够看到作业执行的效果,代码中让主线程睡眠10秒钟,之后关闭调度器。

这个简单的示例展示了Quartz的基础用法,包括如何定义作业、触发器以及如何启动和停止调度器。通过这个例子,咱们可以看到,尽管只是打印了一句“你好,Quartz!”,但背后涉及到的Quartz的配置和使用方法是相当丰富的。这为咱们后续探索更复杂的任务调度提供了坚实的基础。

第四章:任务调度进阶

经过前面的章节,咱们已经掌握了Quartz的基础使用方法,包括创建作业、触发器和调度器。现在,小黑要带咱们进入更高级的领域,探讨如何使用Quartz实现复杂的调度需求。这包括使用Cron Trigger定义复杂的调度策略、使用监听器监控作业的生命周期以及如何处理异常。

使用Cron Trigger实现复杂调度逻辑

在任务调度中,有时咱们需要按照非常具体的时间表来执行作业,比如“每周一上午10:15执行”或“每个月最后一个工作日下午5:00执行”。这时,Cron Trigger就派上了用场。Cron表达式是一种强大的定义时间计划的方式,它允许咱们以几乎任何可能的方式来指定作业的执行计划。

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class AdvancedQuartzExample {
    public static void main(String[] args) {
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();

            JobDetail job = JobBuilder.newJob(HelloJob.class)
                    .withIdentity("job2", "group1")
                    .build();

            // 每周一上午10:15执行的Cron Trigger
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger2", "group1")
                    .withSchedule(CronScheduleBuilder.cronSchedule("0 15 10 ? * MON"))
                    .build();

            scheduler.scheduleJob(job, trigger);

            // 让调度器运行一段时间后关闭
            Thread.sleep(60000);
            scheduler.shutdown();

        } catch (SchedulerException | InterruptedException se) {
            se.printStackTrace();
        }
    }
}

在这个例子中,咱们使用了CronScheduleBuilder.cronSchedule("0 15 10 ? * MON")来创建一个Cron Trigger,这个表达式的意思是“每周一上午10:15执行”。

任务监听器的作用和使用方法

监听器在Quartz中扮演着重要的角色,它允许咱们在作业执行的不同阶段插入自定义逻辑,比如作业执行前后发送通知或者记录日志。Quartz提供了几种类型的监听器,但最常用的是JobListenerTriggerListener

public class MyJobListener implements JobListener {

    @Override
    public String getName() {
        return "MyJobListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        // 作业即将执行时调用
        System.out.println("Job is about to be executed.");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        // 作业执行被否决时调用
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        // 作业执行完成后调用
        System.out.println("Job was executed.");
    }
}

在定义了监听器后,需要将其注册到调度器中:

scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
异常处理和任务持久化

在任务执行过程中可能会遇到各种异常情况,Quartz允许咱们通过实现Job接口的execute方法来捕获和处理这些异常。此外,Quartz还支持任务持久化,这意味着作业和触发器的信息可以存储在数据库中,即使应用程序重启,调度信息也不会丢失。

这章通过介绍Cron Trigger、任务监听器以及异常处理和任务持久化,展示了Quartz在处理复杂调度需求时的强大能力。

第五章:动态任务调度

随着应用的发展,咱们可能会遇到需要在运行时动态添加、修改或删除任务的场景。这就要求任务调度系统不仅要能够按照预设计划执行任务,还要能够灵活应对需求的变化。幸运的是,Quartz提供了这样的灵活性,让小黑来带咱们看看如何实现动态任务调度。

动态添加任务

动态添加任务意味着在应用运行期间,根据具体的业务需求,创建并调度新的作业。这通常涉及到创建新的JobDetailTrigger对象,并使用调度器将它们注册到系统中。

public void addJob(Scheduler scheduler, String jobName, String jobGroup, String triggerName, String triggerGroup, Class<? extends Job> jobClass, String cronExpression) throws SchedulerException {
    // 定义作业,并与我们的Job类关联
    JobDetail job = JobBuilder.newJob(jobClass)
            .withIdentity(jobName, jobGroup)
            .build();

    // 定义触发器,使用传入的cron表达式
    Trigger trigger = TriggerBuilder.newTrigger()
            .withIdentity(triggerName, triggerGroup)
            .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
            .build();

    // 调度作业
    scheduler.scheduleJob(job, trigger);
}

在这个方法中,咱们通过参数接收作业名称、组名、触发器名称、组名、作业类以及cron表达式。然后,使用这些参数创建作业和触发器,并将它们注册到调度器中。

动态修改任务

有时候,咱们可能需要修改现有任务的执行计划。Quartz允许咱们修改触发器的属性,从而改变作业的调度。

public void rescheduleJob(Scheduler scheduler, String triggerName, String triggerGroup, String newCronExpression) throws SchedulerException {
    TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
    // 获取旧的触发器
    CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
    // 定义新的触发器,使用新的cron表达式
    Trigger newTrigger = oldTrigger.getTriggerBuilder()
            .withSchedule(CronScheduleBuilder.cronSchedule(newCronExpression))
            .build();
    // 重新调度作业
    scheduler.rescheduleJob(triggerKey, newTrigger);
}

通过获取旧触发器的TriggerKey,咱们可以创建一个新的触发器,并将其与新的cron表达式关联,然后使用rescheduleJob方法更新任务调度。

动态删除任务

在某些场景下,咱们可能需要删除不再需要的任务。Quartz提供了简单的方法来实现这一点。

public void deleteJob(Scheduler scheduler, String jobName, String jobGroup) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    // 删除作业
    scheduler.deleteJob(jobKey);
}

通过指定作业的JobKey,咱们可以从调度器中删除该作业。

这章展示了如何在Quartz中实现动态任务调度,包括如何在运行时添加、修改和删除任务。这些功能为应对快速变化的业务需求提供了强大的支持,使得Quartz成为一个灵活且强大的任务调度解决方案。通过实现这些动态调度功能,咱们的应用能够更加灵活地适应业务变化,提高效率和响应速度。

第六章:集群中的任务调度

随着应用规模的扩大,单一的任务调度器可能已经无法满足需求,特别是在高可用性和负载均衡方面。在这种情况下,将Quartz部署在集群模式下就显得尤为重要。集群模式能够确保即使某个节点失败,调度的任务也能由集群中的其他节点接管,从而提高了系统的可靠性和可用性。本章,小黑将介绍在集群环境下如何配置和使用Quartz,以及处理任务冲突和容错的策略。

Quartz集群配置

在Quartz集群中,所有的调度器实例都会共享一个数据库,这样它们就能共享作业和触发器的状态信息。要配置Quartz以在集群模式下运行,主要需要做的就是配置Quartz的属性文件(通常是quartz.properties),以便使用相同的数据库。

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz?useSSL=false
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = secret
org.quartz.dataSource.myDS.maxConnections = 5

在这个配置中,isClustered属性被设置为true,表示Quartz将在集群模式下运行。此外,还需要配置数据库连接信息,因为集群中的所有调度器实例都需要访问同一个数据库。

集群任务调度的原理

在集群模式下,Quartz通过数据库锁来确保同一个任务不会被多个节点同时执行。当一个调度器实例尝试执行一个任务时,它会先在数据库中对该任务加锁。如果加锁成功,该实例就会执行任务;否则,意味着有其他实例已经在执行该任务,当前实例就会放弃执行。

处理集群环境下的任务冲突和容错

为了有效地在集群环境下管理任务调度,需要考虑到任务冲突和容错的问题。任务冲突通常发生在两个或两个以上的调度器实例尝试同时执行同一个任务的情况。如前所述,Quartz通过数据库锁机制来避免这种情况的发生。

容错机制是指当一个调度器实例失败时,集群中的其他实例能够接管未完成的任务。Quartz通过持续检查数据库中的锁和任务状态来实现这一点。如果一个实例在执行任务时失败,数据库中的锁将被释放,其他实例就可以接管并执行该任务。

通过部署Quartz到集群环境,咱们能够提高任务调度的可靠性和可用性,确保即使在部分节点出现故障的情况下,任务调度也能正常进行。这对于构建高可用的大规模应用至关重要。通过本章的介绍,希望咱们能够对Quartz在集群模式下的配置和运行有一个更深入的理解。

第七章:性能优化和最佳实践

随着任务调度的规模和复杂性的增加,性能优化变得尤为重要。一个高效的任务调度系统能够确保任务准时执行,同时最大限度地减少资源消耗。本章,小黑将分享一些关于Quartz性能优化的策略和技巧,以及在使用Quartz时的一些最佳实践。

性能优化策略
1. 合理配置线程池

Quartz使用线程池来执行作业,线程池的大小对性能有直接影响。如果线程池设置得太小,可能会导致任务排队等待执行,从而影响任务的及时性。反之,线程池设置得太大,又会增加系统的负担。因此,根据实际需求合理配置线程池大小是很重要的。

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
2. 使用数据库连接池

在集群环境下,Quartz通过数据库来共享任务和触发器的状态信息。使用数据库连接池不仅可以减少连接数据库的开销,还可以避免因为频繁打开和关闭数据库连接而造成的资源浪费。

3. 精确的触发器设置

避免使用过于频繁的触发器设置,尤其是在有大量作业需要调度时。过于频繁的触发可能会导致调度器过载,并且增加数据库的压力。在设置触发器时,尽量根据实际业务需求,选择合理的执行频率。

最佳实践
1. 分离长短作业

将长时间运行的作业与短时间运行的作业分开处理,可以提高调度器的效率。对于长时间运行的作业,可以考虑使用单独的调度器或线程池来执行,避免阻塞短作业的执行。

2. 监控和日志记录

监控Quartz的运行状态和性能指标,可以帮助及时发现和解决问题。同时,合理的日志记录策略不仅可以帮助调试,还可以作为系统运行状态的重要记录。

scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), EverythingMatcher.allTriggers());
3. 安全考虑

在配置Quartz时,尤其是在集群环境下,需要注意数据库的安全配置,避免敏感信息泄露。同时,对于执行的作业,如果涉及到敏感操作,需要进行适当的权限控制。

通过遵循这些性能优化策略和最佳实践,咱们可以构建一个既高效又可靠的任务调度系统。Quartz作为一个功能强大的任务调度框架,能够帮助咱们满足各种复杂的调度需求,但也需要咱们在使用时注意合理配置和优化,以发挥其最大的效能。

第八章:案例研究和总结

在前面的章节中,小黑带领咱们一起深入探讨了Quartz的基础知识、进阶用法、动态任务调度、集群部署以及性能优化和最佳实践。现在,通过几个实际的案例研究,咱们将看到Quartz如何在项目中解决复杂的任务调度问题,并从中总结一些关键的学习点。

案例研究一:电子商务平台的订单处理

在一个快速发展的电子商务平台中,需要定时处理订单状态,比如自动取消长时间未支付的订单、自动确认收货等。这些任务需要精确的时间控制和高度的可靠性。通过使用Quartz,平台开发团队能够定义复杂的调度逻辑,确保每项任务都能按时准确执行。

  • 挑战:确保在高并发环境下,定时任务的准确性和高效性。
  • 解决方案:利用Quartz的集群功能,将任务调度分布在多个节点上执行,通过数据库保持任务状态的同步,确保任务执行的一致性和可靠性。
案例研究二:金融系统中的报表生成

在一个金融系统中,报表生成是一个资源密集型的任务,需要在夜间低峰时段执行。这些报表任务不仅需要按照复杂的时间表来执行,还需要在执行前后进行数据的准备和清理工作。

  • 挑战:如何在保证系统性能的同时,确保报表按计划生成。
  • 解决方案:通过Quartz的Cron Trigger定义精确的执行计划,同时使用JobListener监听作业的执行状态,进行必要的数据准备和清理。
总结

通过这些案例研究,咱们可以看到Quartz作为一个强大的任务调度框架,能够帮助解决各种复杂的调度问题。无论是需要精确控制执行时间的场景,还是需要在分布式环境中保持任务执行一致性的需求,Quartz都能提供有效的解决方案。

关键学习点

  • Quartz的灵活性和强大功能使其成为处理复杂任务调度问题的理想选择。
  • 通过合理配置和使用Quartz的高级特性,如集群支持和动态任务调度,可以大幅提升任务调度的效率和可靠性。
  • 性能优化和遵循最佳实践对于构建高效、可靠的任务调度系统至关重要。

更多推荐

详解SpringCloud之远程方法调用神器Fegin

掌握Java Future模式及其灵活应用

小黑整的视頻会园优惠站

使用Apache Commons Chain实现命令模式

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习笔记】深度学习实战 | LeNet

简要声明 学习相关网址 [双语字幕]吴恩达深度学习deeplearning.aiPapers With CodeDatasets 深度学习网络基于PyTorch学习架构&#xff0c;代码测试可跑。本学习笔记单纯是为了能对学到的内容有更深入的理解&#xff0c;如果有错误的地方&#xff0c;恳请包容和指正。 参考文献…

基于ssm网络办公系统论文

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

【Linux】Linux安装

Linux安装&#xff08;保姆级教程&#xff09; 准备工具下载链接 Linux镜像系统官网&#xff08;Centos版本&#xff09;&#xff1a;https://www.centos.org/ 虚拟机下载官网&#xff1a;https://www.vmware.com 注&#xff1a;Linux是一种系统统称&#xff0c;就像Windows…

小米科技分享:深入解析阿里巴巴面试题之SQL查询

大家好,我是小米,今天要和大家分享的是在阿里巴巴面试中常见的SQL查询题目。SQL查询是数据库领域中的基础,但也是一个非常重要的技能,无论是在面试中还是实际工作中,都有着举足轻重的地位。让我们一起深入了解一下吧! SQL语句的执行过程 首先,我们来了解一下SQL语句的执…

【Java】基本数据类型、包装类与字符串间的转换 例题

写在前面&#xff1a; 关于这道题&#xff0c;初见感觉有点cpu烧坏了&#xff0c;准确来说是看了网上的一些讲解都感觉不尽人意。自己整理了一下&#xff0c;希望能帮助到大家。 题目&#xff1a; 如下两个题目输出结果相同吗&#xff1f;各是什么。 Object o1 true ? new…

悄悄告诉你,干洗店60%业务都在自这里

洗衣管理软件&#xff0c;让生活更轻松&#xff01;无论是洗衣还是洗鞋&#xff0c;这款软件都能帮你轻松搞定一切&#xff1a;预约、洗涤进度查询、顾客反馈&#xff0c;一切尽在指尖。 店家使用软件智能管理收衣收鞋&#xff0c;从接收、洗涤到通知顾客取衣&#xff0c;全程自…

【UE 材质】制作加载图案(2)

在上一篇&#xff08;【UE 材质】制作加载图案&#xff09;基础上继续实现如下效果的加载图案 效果 步骤 1. 复制一份上一篇制作的材质并打开 2. 添加“Floor”节点向下取整 除相同的平铺数 此时的效果如下 删除如下节点 通过“Ceil”向上取整&#xff0c;参数“Tiling”默认…

4、正则表达式、本地存储

一、正则表达式 1、定义 用事先定义好的一些特定字符&#xff0c;这样的字符组合&#xff0c;组合成一个“规则字符串” 2、正则的组成 特殊字符 字母、数字、下划线、中文、特殊字符… 元字符&#xff08;常用&#xff09; 1、\d 匹配至少有一个数字 var reg /\d/ /…

东莞IBM服务器维修之IBM x3630 M4阵列恢复

记录东莞某抖音电商公司送修一台IBM SYSTEM X3630 M4文档服务器RAID6故障导致数据丢失的恢复案例 时间&#xff1a;2024年02月20日&#xff0c; 服务器品牌&#xff1a;IBM System x3630 M4&#xff0c;阵列卡用的是DELL PERC H730P 服务器用途和用户位置&#xff1a;某抖音电…

新品齐发!小牛电动打造全场景高端化产品阵列!

2 月 29 日&#xff0c;全球智能城市出行品牌小牛电动发布“新世代性能旗舰”电摩NX、电自NXT&#xff0c;以及“全场景智驾越野电摩”X3三款新品。同时&#xff0c;与知名体育电竞俱乐部——JDG京东电子竞技俱乐部携手&#xff0c;打造“英雄的联盟”超级形象&#xff0c;引领…

文件误删除怎么恢复?盘点4个有效方法!

“我有一些很重要的工作文件保存在电脑上了&#xff0c;但是刚刚操作的时候却发现有些文件被误删了。有什么简单的误删文件恢复方法吗&#xff1f;” 在日常生活和工作中&#xff0c;我们可能都需要在电脑上保存各种各样的文件。如果在操作时误删比较重要的文件&#xff0c;很多…

进阶了解C++(4)——多态

在上篇文章中&#xff0c;简单的介绍了多态中的概念以及其相关原理。本文将针对多态中其他的概念进一步进行介绍&#xff0c;并且更加深入的介绍关于多态的相关原理。 目录 1. 抽象类&#xff1a; 2. 再谈虚表&#xff1a; 3. 多继承中的虚函数表&#xff1a; 1. 抽象类&am…

Mybatis-Plus介绍

目录 一、Mybatis-Plus简介 1.1、介绍 1.2、特性 1.3、架构 1.4、Mybatis-Plus与Mybatis的区别 二、快速入门 2.1、首先创建数据库mybatis-plus 2.2、创建user表 2.3、插入数据 2.4、创建Spring-Boot项目 2.5、添加依赖 2.6、连接数据库 一、Mybatis-Plus简介 1.1、…

Springboot项目集成短信验证码(超简单)

操作流程 注册验证码平台创建验证码模版开始集成&#xff08;无需引入第三方库&#xff09; 注册并登陆中昱维信验证码平台 获取AppID和AppKey。 创建验证码模版 创建验证码模版&#xff0c;获取验证码模版id 开始集成 创建controller import org.springframework.web.bi…

跨域引起的两个接口的session_id不是同一个

来源场景&#xff1a; RequestMapping(“/captcha”)接口设置了SESSION_KEY&#xff0c;也能获取到&#xff0c;但是到了PostMapping(“/login”)接口就是空的&#xff0c;由于跨域导致的两个session_id不是同一个 /*** 系统用户 前端控制器*/ Controller CrossOrigin(origins…

自定义el-dialog的样式

实现效果&#xff1a; 样式代码如下&#xff1a;&#xff08;可以写在common.scss文件夹中&#xff09; .el-dialog__header {padding: 16px 20px;border-bottom: 1px solid #DCDFE6;display: flex;align-items: center;.el-dialog__title {font-size: 16px;position: relativ…

MySQL(基础篇)——事务

一.事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作色一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 默认MySQL的事务是自动提交的&#xff0c;也就是说&#xff0c…

在VMware中安装CentOS 7并配置Docker

VMware安装CentOS 7 一、介绍 该文章介绍如何使用启动U盘在虚拟机里面安装系统&#xff0c;虚拟机版本为VMware Workstation 16 pro&#xff0c;Linux版本为CentOS Linux release 7.9.2009 (Core)。 二、安装 1、创建虚拟机 点击创建新的虚拟机 选择典型就可以了&#xf…

spring-boot static-path-pattern如何配置生效

WebMvcAutoConfiguration AbstractUrlHandlerMapping ResourceHttpRequestHandler springboot 版本 2.3.9.RELEASE 一、如何用 yaml配置 spring:mvc:static-path-pattern: /doctest/**resources:static-locations: classpath:/doc/资源文件配置 访问路径 二、原理 第一个问…

幻兽帕鲁联机服务器搭建

幻兽帕鲁联机服务器搭建 开通云服务器 云主机购买|香港云服务器|香港云主机|美国云服务器|弹性云主机租用尽在-特网科技 建议选择4核心 16G内存 10M带宽&#xff0c;可满足6-15人游玩 下载安装脚本 windows系统: 下载 http://downinfo.myhostadmin.net/palserver/install…