创建一个坚固的备份系统
在Foreach,我们拥有Synology RS815 +来存储所有备份。 这些备份来自我们网络中的不同来源,例如路由器,交换机,数据库服务器,Web服务器,应用程序日志文件,邮件服务器等等。
Synology NAS使配置这些备份的文件共享和配额变得非常容易。 但是,它缺少一些功能:
- 监视文件共享上的配额(硬配额以及没有配额的文件共享)。
- 删除由保留策略预定义的过时备份文件。
- 验证备份文件,以确保我们实际收到了备份文件。
在此博客文章中,我们将概述如何设置一个Spring Boot 2应用程序,该应用程序公开一个GUI,并可以使用(例如)Zabbix进行监视。
哦,备份,您在哪里?
您可能会认识到以下问题:
您需要还原备份并仅转到备份位置以查看备份文件不存在。 您开始四处寻找,发现备份从未到达您的NAS,因为超出了共享文件夹的配额。 或更糟糕的是,您的整个NAS实际上已满。 该死的! 我们应该清理3年前的备份文件!
如果神灵对您有好处,您实际上会找到备份文件,但是该文件可能已过时或过旧而无法还原。 您所需的数据最多需要几天,而不是三周前。 达尼特! 我们应该检查备份任务是否真的有效!
尤里卡!
为了解决这个问题,我们创建了一个Spring Boot 2.0应用程序,该应用程序具有多个角色:
- 它公开了一个基于Bootstrap的GUI(可以对我们(是)读取)和一个监视平台(在我们的情况下为Zabbix)。
- 它监视Synology中配置的所有文件共享,并在接近配额限制时向我们发出警告。
- 它根据保留策略从文件共享中删除旧的备份文件。
- 它会验证备份文件并确保文件足够新,并且有一定数量的历史记录可用。
最终结果如下所示:
高级设置
我们使用Spring Initialzr用Java 8和Spring Boot 2.0生成了一个Maven项目。 Thymeleaf 3和Bootstrap 3用于创建概述页面。
使用jquery / bootstrap webjar,我们能够在短短几分钟内设置一个Controller和原型布局。
Global status: OK
是由Zabbix监视的必需字符串。 如果任何基础状态失败,则全局状态也将失败。
我们使用Spring Boot胖子在自己的文件共享中部署了应用程序(您不希望应用程序日志文件填充其他备份文件共享,对吗?)。 要创建可执行jar,请将以下内容添加到pom.xml
。 请参阅文档以获取更多信息。
<build><finalName>checkback</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><executable>true</executable></configuration></plugin></plugins>
</build>
Synology NAS并未真正提供标准的System V环境。 为了利用嵌入在可执行jar中的启动/停止脚本,我去阅读了嵌入式启动脚本的实际工作方式。 您可以在GitHub上找到它。
这里的重点是:
# Follow symlinks to find the real jar and detect init.d script
cd "$(dirname "$0")" || exit 1
[ [ -z "$jarfile" ] ] && jarfile=$(pwd)/$(basename "$0")
while [ [ -L "$jarfile" ] ]; doif [ [ "$jarfile" =~ init\.d ] ]; theninit_script=$(basename "$jarfile")elseconfigfile="${jarfile%.*}.conf"# shellcheck source=/dev/null[ [ -r ${configfile} ] ] && source "${configfile}"fijarfile=$(readlink "$jarfile")cd "$(dirname "$jarfile")" || exit 1jarfile=$(pwd)/$(basename "$jarfile")
done
基本上,它检查.jar文件所在的位置。 如果.jar文件实际上位于一个名为“init.d中”目录(位置并不一定是/etc/init.d中),它将作为启动/停止脚本来处理。 您只需要在某个地方创建一个init.d目录,并创建一个从开始/停止脚本到可执行jar的符号链接。
在我们的环境中,我们最终为应用程序提供了以下结构:
/volume1/checkback
(此应用程序的文件共享)
/volume1/checkback/checkback.jar
Boot可执行jar)
/volume1/checkback/checkback.conf
Boot应用程序配置文件)
/volume1/checkback/init.d/checkback.sh
(到/volume1/checkback/checkback.jar的符号链接)
有了这个,我们可以启动/停止并查看我们的Spring Boot应用程序的状态。 还可以在Synology NAS中创建启动触发器,这样,只要您的Synology重新启动其补丁程序,您的应用程序就会启动。
user@synology:/volume1/checkback/init.d$ ./checkback.sh status
Running [18657]
user@synology:/volume1/checkback/init.d$
checkback.conf
文件包含我们的生产配置文件的位置,并且还指定了日志文件夹(而不是默认的/ var / log位置)
bash-4.3# cat checkback.conf
RUN_ARGS="--spring.config.location=/volume1/checkback/synology-config.yml"
LOG_FOLDER="/volume1/checkback"
bash-4.3#
现在我们已经建立并运行了结构,我们可以开始编码测试了。 每当我开发应用程序时,我都希望它具有一些测试数据或生产数据的快照。 为此,您可以阅读有关模拟用于JUnit测试的Synology数据的博客 。
现在,让我们开始编码。 我们的应用程序使用YAML文件来定义要检查配额的文件夹以及需要验证的备份集。 它们由Spring映射到@ConfigurationProperties
。 配置看起来像这样:
checkback:cron: '0 0 10 * * *'slack.channel: '#infra'quota-configs:- path: /volume1excludePattern: '^@.*'backup-set-configs:- name: Mikrotik Backupsuri: /volume1/backupftp/mikrotik_backuptype: DISKfile-set:- name: fe-prodnet01 exportfilterPattern: '.*fe-prodnet01-.*\.rsc'- name: fe-prodnet11 backupfilterPattern: '.*fe-prodnet11.*\.backup'- name: Exchange Backupsuri: /volume1/pex/backupstype: DISKfile-set:- name: Exchange pstsfilterPattern: '.*\.pst'groupByPattern: '.*\/backups\/(\d{4}-\d{2}-\d{2})\/'groupByPatternHasDatePattern: 'yyyy-MM-dd'deletePolicy:deleteEmptyDirectories: true
如您所见,我们每天10:00更新状态,这由YAML中的cron条目定义。 如果有任何警告,我们也会将其发布到我们的Slack频道。 为此,我们使用jSlack ,但还有许多其他选择。
检查配额
为了检查配额,我们定义了检查配额的路径。 默认情况下,我们排除以“ @”开头的目录,它们是Synology特定的目录。
quota-configs:- path: /volume1excludePattern: '^@.*'
在Synology上,您可以为特定文件共享指定配额。 我们称这些硬配额。 如果您未设置配额(或忘记设置配额),则默认设置为20GB; 这就是我们所说的软配额。
要检查Synology的配额,可以使用btrfs
命令:
bash-4.3# /sbin/btrfs qgroup show -f /volume1/share -f -r --raw
WARNING: Qgroup data inconsistent, rescan recommended
qgroupid rfer excl max_rfer
-------- ---- ---- --------
0/1931 2559573532672 0 4398046511104
这种方法有一个问题:
- 从警告中可以看到,
btrfs
根据时间表计算当前使用量,并且数据不一致。 要获得准确的近实时值,您将必须执行brtfs quota rescan <path>
,等待其完成,然后在rfer
字段中获取估计的大小。
由于brtfs的计算不一致,因此我们的应用程序将按目录执行命令,并且仅考虑max_rfer
。 如果max_rfer
等于none
,则未设置配额,默认值为20GB。
以下一段Java代码执行此命令并解析输出。
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/sbin/btrfs", "qgroup", "show", "-f", f.toString(), "-r", "--raw");
String MAX_RFER = "";LOG.info("executing command: " + f.toString());
try (InputStreamReader inputStreamReader = new InputStreamReader(processBuilder.start().getInputStream())) {
try (LineNumberReader reader = new LineNumberReader(inputStreamReader)) {String line;while ((line = reader.readLine()) != null) {LOG.info(reader.getLineNumber() + " : " + line);if (reader.getLineNumber() == 3) {MAX_RFER = line.split("\\s+")[3];break;}}
}
} catch (IOException ignore) {
LOG.error("Exception getting quota from btrfs command", ignore);
}
try {return Long.parseLong(MAX_RFER);
} catch (NumberFormatException ignore) {return 0;
}
现在我们有了配额限制,我们只需要计算目录的大小即可。 而不是依靠brtfs或du ,我们只是让Java NIO来完成这项工作。
AtomicLong totalSize = new AtomicLong();
Files.walkFileTree(f, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {totalSize.addAndGet(Files.size(file));return FileVisitResult.CONTINUE;}
});quotaStatus.used(totalSize.get());
剩下要做的就是计算剩余的百分比并将其显示在Bootstrap进度栏中 。
可以使用Apache Commons FileUtils的byteCountToDisplaySize来格式化字节,以使它们可以被人类读取 。 但是,此方法具有以不一致的方式四舍五入值的不好的感觉。
作为替代方案,我们使用字节单位 ,并通过以下方式使用它来获得非常可选的两点十进制值:
public class FileSizeUtil {public static String readableFileSize(long size) {return BinaryByteUnit.format(size,"#,##0.##");}
}
如果您认为我们已经完成了,那么您会忘记一个警告。 要在应用程序内部执行brtfs
命令,您必须是root用户。 幸运的是,此应用程序位于我们的内部网络上,这样做的风险是有限的。
如果您的Synology与互联网建立公共连接,请不要以root用户身份运行应用程序。
要运行Spring启动应用程序的根,刚chown
文件为根 。 Spring Boot将为您完成其余工作,因为它始终在拥有jar文件的用户下运行应用程序。
bash-4.3# chown root:root checkback.jar
你完成了! 我们都准备检查配额。
下周再回来查看有关如何监视备份集的摘要。
翻译自: https://www.javacodegeeks.com/2018/05/creating-a-sturdy-backup-system.html
创建一个坚固的备份系统相关推荐
- 安装linux系统initrd,修改initrd,创建一个微型的linux系统
创建一个MiniLinux: 通过对RamDisk(Initrd)分析,现在了解了initrd的主要原理及工作流程,为了加深对该过程的理解,下面使用initrd创建一个微型的linux系统,也更加深对 ...
- 在kaldi工具包使用小数字语料库创建一个简单的ASR系统(番外篇)
相信很多人已经看过kaldi英文官网上关于该系统的搭建流程.虽然官方已经写的很通俗易懂,但是第一次接触的话还是不可避免的会碰到许多坑.恰巧最近实践了一下,把整个实践过程写了下来.一是方便自己后续回顾本 ...
- 如何在win10系统下创建一个虚拟机使用winxp系统
日常使用的电脑一般是基于win10或者win11系统的,但是在一些特定的场景下,比如我们测试芯片时,它要求电脑配置必须是win7或者winxp,以及软件安装环境必须是较低版本的windows系统,这里 ...
- 创建一个集群和探索ProxmoxGUI
创建一个集群和探索ProxmoxGUI ProxmoxVE可以被用于独立地不被部分的一个集群.但为了要真正使用Proxmox在其充分的潜力,一个集群使许多更先进的功能,如为集中管理,高可用性,以及实时 ...
- SAP PM 入门系列11 - 一个维护通知单只能创建一个维护订单?
SAP PM 入门系列11 - 一个维护通知单只能创建一个维护订单? 在SAP系统里,执行事务代码IW34,输入Notification号码100314924,以及Order type ZM03,试图 ...
- java监视器_监视和管理备份系统
java监视器 上一次我们建立了一个强大的备份系统,现在我们将研究如何监视备份集. 我们需要验证是否正确清理了备份集(这称为删除策略),并且它们是一致的(称为一致性策略). 备份集可以包含多个文件集. ...
- 海域动态监视监测管理系统_监视和管理备份系统
海域动态监视监测管理系统 上一次我们建立一个强大的备份系统时 ,现在我们将研究如何监视备份集. 我们需要验证是否正确清理了备份集(这称为删除策略),并且它们是一致的(称为一致性策略). 备份集可以包含 ...
- windows系统下 第一次使用GitBash工具创建代码仓库且备份gitHub
介绍 gitHub: 分布式GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub.全世界最大的代码托管平台 Git: Git是目前世界上 ...
- 开源分布式Job系统,调度与业务分离-如何创建一个计划HttpJob任务
项目介绍: Hangfire:是一个开源的job调度系统,支持分布式JOB!! Hangfire.HttpJob 是我针对Hangfire开发的一个组件,该组件和Hangfire本身是独立的.可以独立 ...
最新文章
- [JavaScript] JavaScript 运算符与流程控制
- 每日一皮:就像我的编程,虽然过程不咋地,结果还不错...
- 链表快速排序python_Python一行代码实现快速排序的方法
- html超市代码,前端 CSS : 5# 纯 CSS 实现24小时超市
- Nebula3渲染层: Graphics
- PHP中“简单工厂模式”实例讲解(转)
- linux不解压情况下查看压缩包内文件的总行数、文件列表的数目
- 编程到底难在哪里?—— 《人月神话》阅读分享
- 忘记网站服务器密码怎么办,忘记远程服务器的密码怎么办
- 永久免费使用免费20G空间的推荐
- U盘无法格式化的原因及解决方法
- Google Chrome开发者工具-移动仿真:网络带宽控制
- Java Web 开发后续(二)
- 2019牛客暑期多校训练营(第四场)----E-	triples II
- 硬盘备份到新电脑,你需要知道这个技巧
- 每日一题:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
- Android Studio WiFi 之 获取 WiFi 名称、IP、Mac
- GitOps | 一种云原生的持续交付模型
- 在校外,如何免费下载知网上的文献论文的方法
- 项目经理必须知道的7种项目管理方案