创建一个坚固的备份系统
在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
總結
以上是生活随笔為你收集整理的创建一个坚固的备份系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想ibm官网(联想的ibm)
- 下一篇: java设计模式迭代器模式_Java中的