NBlog Java定时任务-备份MySQL数据

NBlog部署维护流程记录(持续更新):https://blog.csdn.net/qq_43349112/article/details/136129806

为了避免服务器被攻击,给博客添加了一个MySQL数据备份功能。

此功能是配合博客写的,有些方法直接用的已有的,不会再详细展示代码。

备份大致功能步骤如下:

  • 使用mysqldump备份数据(完成)
  • 对备份文件进行压缩(完成)
  • 压缩文件上传到OSS(完成)
  • 文件清理(完成)
  • 邮件通知(TODO)
  • 适应化改造(TODO)

详细步骤见下文

CG

0.备份任务主逻辑

目前暂时使用定时任务触发,以下仅为核心代码。

    /*** 定时任务,每周一凌晨四点,备份MySQL的数据* 备份逻辑:* 1.mysql数据备份到文件* 2.备份文件压缩* 3.压缩文件上传到OSS* 4.残留文件清理* 5.备份结果的邮件通知 //TODO* 6.适应化改造,改成类似NBlog中的定时任务 //TODO*/@Scheduled(cron = "0 0 4 * * 1")public void backUpMySQLData() {checkDir(backupDir);String dateFormat = simpleDateFormat.format(new Date());String fileName = String.format("cblog-%s.sql", dateFormat);String compressedFileName = fileName + ".zip";String dataPath = backupDir + File.separator + fileName;String compressedFilePath = backupDir + File.separator + compressedFileName;try {log.debug("mysql备份开始");// 1.mysql数据备份backupData(dataPath);// 2.文件压缩FileUtils.compressFile(dataPath, compressedFilePath);// 3.上传到OSSString uploadLink = UploadUtils.upload(compressedFilePath);log.info("备份文件({})已上传至OSS({})", compressedFilePath, uploadLink);// 4.清除残留文件FileUtils.delFileByPath(dataPath, compressedFilePath);} catch (IOException e) {log.error("mysql数据备份失败");log.error(e.getMessage());}}

1.mysqldump备份

通过Runtime.getRuntime().exec(xxx)执行备份命令,保存到指定路径下。

由于我的MySQLdocker部署,因此使用了docker exec命令。

命令的执行结果会比较长,日志级别建议低一些,下面用的debug级别。

需要注意exec(cmds)的参数格式,写错的话命令不会执行并且不报错,排查了半个下午。

    /*** MySQL数据备份* @param dataPath 备份文件的保存路径* @throws IOException*/private void backupData(String dataPath) throws IOException {long start = System.currentTimeMillis();String cmd = String.format("docker exec mysql mysqldump -u%s -p%s cblog > %s", dataSourceProperties.getUsername(), dataSourceProperties.getPassword(), dataPath);String[] cmds = {"sh", "-c", cmd};log.debug("欲执行命令:{}", cmd);try (InputStream inputStream = Runtime.getRuntime().exec(cmds).getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {String line = bufferedReader.readLine();while (line != null) {log.debug(line);line = bufferedReader.readLine();}}long end = System.currentTimeMillis();log.info("mysql备份命令执行成功,耗时:{}ms", end - start);}

2.备份文件压缩

压缩成zip格式,核心代码如下:

     * 压缩文件到指定路径* @param oriFilePath 要压缩的原文件路径* @param compressedFilePath 压缩后的文件存放路径* @throws IOException IO异常,不在catch模块捕捉,交给调用方自行处理*/public static void compressFile(String oriFilePath, String compressedFilePath) throws IOException {File file = new File(oriFilePath);File zipFile = new File(compressedFilePath);try (FileInputStream fileInputStream = new FileInputStream(file);ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()))){zipOutputStream.putNextEntry(new ZipEntry(file.getName()));int temp = 0;while ((temp = fileInputStream.read()) != -1) {zipOutputStream.write(temp);}}log.info("文件压缩完成");}

3.上传至OSS

核心代码如下

    public String upload(String filepath) throws IOException {File file = new File(filepath);String uploadName = aliyunProperties.getBackupPath() + "/" + file.getName();PutObjectRequest putObjectRequest = new PutObjectRequest(aliyunProperties.getBucketName(), uploadName, file);return uploadByOSS(putObjectRequest, uploadName);}private String uploadByOSS(PutObjectRequest putObjectRequest, String uploadName) throws IOException {try {ossClient.putObject(putObjectRequest);return String.format("https://%s.%s/%s", aliyunProperties.getBucketName(), aliyunProperties.getEndpoint(), uploadName);} catch (Exception e) {throw new RuntimeException("阿里云OSS上传失败");}}

4.清除残留文件

上传后,备份文件和压缩文件已经无用,删除掉即可:

    public static void delFileByPath(String... paths) {if (paths == null) {return;}for (String path : paths) {File file = new File(path);del(file);}}private static void del(File file) {String filePath = file.getAbsolutePath();file.delete();log.info("{}文件已清除", filePath);}

5.邮件通知结果(TODO)

6.适应化改造(TODO)

NBlog定时任务可以在前端配置,自由修改触发时间,并且可以直接触发。

目前的暂时写死了,下周改造下。

X、测试

确定定时任务触发后,OSS能看到文件即可

image-20240317171232043

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

如何在不带备份的情况下恢复 Android 手机照片?

你的 Android 手机出了什么问题? Android 手机上的垃圾文件过多。 您的 Android 手机屏幕黑屏。 您的手机蓝屏死机。 您的设备卡在启动屏幕上。 电话停止工作。 手机一直关机。 ... 您是否遇到过以上情况并将您的 Android 手机恢复出厂设置?如果是这样&…

cartographer学习与使用

记录一下在配置和使用cartographer建图时遇到的各种问题吧。 我的数据 配置文件&#xff1a; my_rslidar.launch <launch> <param name"/use_sim_time" value"false" /> <!--启动建图节点--> <node name"cartographer_n…

【人工智能】英文学习材料01(每日一句)

&#x1f33b;个人主页&#xff1a;相洋同学 &#x1f947;学习在于行动、总结和坚持&#xff0c;共勉&#xff01; 目录 1.Natural Language Processing&#xff0c;NLP&#xff08;自然语言处理&#xff09; 2.Machine Learing&#xff0c;ML&#xff08;机器学习&#xf…

【Java基础知识总结 | 第三篇】深入理解分析ArrayList源码

文章目录 3.深入理解分析ArrayList源码3.1ArrayList简介3.2ArrayLisy和Vector的区别&#xff1f;3.3ArrayList核心源码解读3.3.1ArrayList存储机制&#xff08;1&#xff09;构造函数&#xff08;2&#xff09;add()方法&#xff08;3&#xff09;新增元素大体流程 3.3.2ArrayL…

pyspark基础 -- DataFrame的理解与案例

DataFrame(df)介绍 datafram就是一个内存中的二维表结构&#xff0c;具备表结构的三个基本属性&#xff1a; 行列表结构描述 在结构层面&#xff0c;pyspark中的StructType对象描述了表结构&#xff0c;StructField对象描述了表的一个列信息&#xff1b;在数据层面&#xff…

网络学习:邻居发现协议NDP

目录 前言&#xff1a; 一、报文内容 二、地址解析----NS/NA 目标的被请求组播IP地址 邻居不可达性检测&#xff1a; 重复地址检测 路由器发现 地址自动配置 默认路由器优先级和路由信息发现 重定向 前言&#xff1a; 邻居发现协议NDP&#xff08;Neighbor Discovery…

html5黑色大气的个人博客全屏滚动个人主页源码HTML+JS+CSS

html5黑色大气的个人博客全屏滚动个人主页源码HTMLJSCSS

企业数据流动安全管理软件(深度解析文章)

企业数据重要性不言而喻&#xff0c;而同时数据的流动和共享也带来了安全风险&#xff0c;如何确保企业数据在流动过程中的安全性&#xff0c;也成为了企业需要面临的重要问题。 企业数据流动安全管理软件的主要功能是监控和管理企业数据的流动过程。 它能够对企业内部的数据…

图解Kafka架构学习笔记(一)

本文参考尚硅谷大数据技术之Kafka。 消息队列 &#xff08;1&#xff09;点对点模式&#xff08;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除&#xff09; 点对点模型通常是一个基于拉取或者轮询的消息传送模型&#xff0c;这种模型从队列中请求信息…

Transformer的前世今生 day02(神经网络语言模型

神经网络语言模型 使用神经网络的方法&#xff0c;去完成语言模型的两个问题&#xff0c;下图为两层感知机的神经网络语言模型&#xff1a; 以下为预备概念 感知机 线性模型可以用下图来表示&#xff1a;输入经过线性层得到输出 线性层 / 全连接层 / 稠密层&#xff1a;假…

使用 pnpm 搭建 monorepo 项目

引言 在我之前的开发经历中&#xff0c;并没有实际使用过 Monorepo 管理项目&#xff0c;尽管之前对此有所了解&#xff0c;但并未深入探究。然而&#xff0c;如今许多开源项目都采纳了 Monorepo 方式&#xff0c;对于不熟悉它的开发者来说&#xff0c;阅读和理解这些项目的源…

【算法与数据结构】堆排序TOP-K问题

文章目录 &#x1f4dd;堆排序&#x1f320; TOP-K问题&#x1f320;造数据&#x1f309;topk找最大 &#x1f6a9;总结 &#x1f4dd;堆排序 堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 建堆 升序&#xff1a;建大堆 降序&#xff1a;建小堆利…

【LabVIEW FPGA入门】定时

在本节学习使用循环计时器来设置FPGA循环速率&#xff0c;等待来添加事件之间的延迟&#xff0c;以及Tick Count来对FPGA代码进行基准测试。 1.定时快捷VI函数 在FPGA VI中放置的每个VI或函数都需要一定的时间来执行。您可以允许操作以数据流确定的速率发生&#xff0c;而无需额…

Apache-Doris基础概念

OLAP数据库Doris 一、Doris架构二、基本概念1. Row & Column2. Partition & Tablet3. 建表示例&#xff08;1&#xff09;列的定义&#xff08;2&#xff09;分区分桶&#xff08;3&#xff09;多列分区&#xff08;4&#xff09;PROPERTIES&#xff08;5&#xff09;E…

多进程数据库不适合作为hive的元数据库

简介 “今天发现一个比较奇怪的现象&#xff0c;因为博主不熟悉mysql&#xff0c;所以在安装hive的使用了postgresql作为hive的元数据库&#xff0c;在测试几个连接工具对hive进行链接&#xff0c;后面再测试的时候发现链接不上了&#xff0c;并且报错日志如下&#xff1a;” …

多标签分类新建模方法

常见的多标签分类方法是同时生成多个标签的logits&#xff0c;然后接一个sigmoid激活函数做二分类。该方法简单直接&#xff0c;但忽略了标签之间的相关性。虽然业界针对该问题提出了很多解决思路&#xff0c;但大多是任务特定&#xff0c;通用性不强&#xff0c;也不够优雅。 …

Spring Cloud Alibaba微服务从入门到进阶(七)(服务容错-Sentinel)

雪崩效应 我们把基础服务故障&#xff0c;导致上层服务故障&#xff0c;并且这个故障不断放大的过程&#xff0c;成为雪崩效应。 雪崩效应&#xff0c;往往是因为服务没有做好容错造成的。 微服务常见容错方案 仓壁模式 比如让controller有自己独立的线程池&#xff0c;线程池满…

julia语言中的决策树

决策树&#xff08;Decision Tree&#xff09;是一种基本的分类与回归方法&#xff0c;它呈现出一种树形结构&#xff0c;可以直观地展示决策的过程和结果。在决策树中&#xff0c;每个内部节点表示一个属性上的判断条件&#xff0c;每个分支代表一个可能的属性值&#xff0c;每…

Mybatis-xml映射文件与动态SQL

xml映射文件 动态SQL <where><if test"name!null">name like concat(%,#{name},%)</if><if test"username!null">and username#{username}</if></where> <!-- collection&#xff1a;遍历的集合--> <!-- …

AI基础知识(2)--决策树,神经网络

1.什么是决策树&#xff1f; 决策树是一类常见的机器学习方法&#xff0c;决策树是基于树的结构来进行决策。决策过程中提出的每一个问题都是对于属性的“测试”&#xff0c;决策的最终结论对应了我们希望的判定结果。一个决策树包含一个根节点&#xff0c;若干个内部节点和若…