В Foreach у нас есть Synology RS815 + для хранения всех наших резервных копий. Эти резервные копии поступают из разных источников в нашей сети, таких как маршрутизаторы, коммутаторы, серверы баз данных, веб-серверы, файлы журналов приложений, почтовые серверы и т. Д.
NAS-устройство Synology упрощает настройку общих файловых ресурсов и квот для этих резервных копий. Тем не менее, ему не хватало нескольких функций:
- Мониторинг квот на общих файловых ресурсах (жесткие квоты, а также на файловые ресурсы без квот).
- Удаление устаревших файлов резервных копий, предопределенных политикой хранения.
- Проверка файлов резервных копий, чтобы убедиться, что мы действительно получили файлы резервных копий.
В этом сообщении мы расскажем, как настроить приложение Spring Boot 2, которое предоставляет графический интерфейс и может отслеживаться, например, с помощью Zabbix.
О резервное копирование, где ты?
Вы можете распознать следующую проблему:
Вам необходимо восстановить резервную копию и перейти в свою папку только для того, чтобы убедиться, что файла резервной копии там нет. Вы начинаете копаться и обнаруживаете, что резервная копия никогда не поступала на ваш NAS, потому что квота вашей общей папки была превышена. Или, что еще хуже, весь ваш NAS был фактически заполнен. Черт! Мы должны были очистить наши резервные файлы 3 года назад!
Если боги несколько хороши для вас, вы действительно найдете файл резервной копии, но он может быть устаревшим или слишком старым для восстановления. Требуемые вами данные должны быть получены не более 3 дней назад, а несколько дней назад. Слей это! Мы должны были проверить, действительно ли задачи резервного копирования работали!
Эврика!
Чтобы решить эту проблему, мы создали приложение Spring Boot 2.0, которое выполняет несколько функций:
- Он предоставляет графический интерфейс, основанный на Bootstrap, который доступен для чтения (да!), И платформу мониторинга (в нашем случае Zabbix).
- Он отслеживает все общие файловые ресурсы, которые настроены в нашей Synology, и предупреждает нас, если лимиты квот близки к достижению.
- Он удаляет старые файлы резервных копий из общих папок на основе политики хранения.
- Он проверяет файлы резервных копий и гарантирует, что файлы достаточно свежие и что имеется определенное количество доступной истории.
Конечный результат выглядит так:
Настройка высокого уровня
Мы использовали Spring Initialzr для создания проекта Maven с Java 8 и Spring Boot 2.0. Thymeleaf 3 и Bootstrap 3 были использованы для создания страницы обзора.
Используя jquery / bootstrap webjars, мы смогли настроить контроллер и макет прототипа всего за несколько минут.
Global status: OK
— обязательная строка, которая отслеживается Zabbix. В случае сбоя какого-либо из базовых статусов глобальный статус также не будет выполнен.
Мы развернули приложение, используя толстую банку Spring Boot в своей общей файловой папке (вы не хотите, чтобы файлы журнала приложения заполняли другие резервные папки, верно?). Чтобы создать исполняемый файл jar, добавьте следующее в ваш pom.xml
. Смотрите документацию для получения дополнительной информации.
01
02
03
04
05
06
07
08
09
10
11
12
|
< 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.
Основной момент здесь:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
# 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" ] ]; do if [ [ "$jarfile" =~ init\.d ] ]; then init_script=$(basename "$jarfile" ) else configfile= "${jarfile%.*}.conf" # shellcheck source=/dev/ null [ [ -r ${configfile} ] ] && source "${configfile}" fi jarfile=$(readlink "$jarfile" ) cd "$(dirname " $jarfile ")" || exit 1 jarfile=$(pwd)/$(basename "$jarfile" ) done |
По сути, он проверяет, где находится файл .jar. Если файл .jar фактически находится в каталоге с именем «init.d» (расположение не должно быть /etc/init.d), он будет рассматриваться как сценарий запуска / остановки. Вам нужно только создать каталог init.d где-нибудь и создать символическую ссылку от сценария start / stop к исполняемому файлу jar.
В нашей среде мы получили следующую структуру приложения:
/volume1/checkback
( /volume1/checkback
папка для этого приложения)
/volume1/checkback/checkback.jar
(исполняемый файл- /volume1/checkback/checkback.jar
Spring Boot)
/volume1/checkback/checkback.conf
(файл конфигурации приложения Spring Boot)
/volume1/checkback/init.d/checkback.sh
(символическая ссылка на /volume1/checkback/checkback.jar)
Имея это в виду, мы можем запускать / останавливать и видеть состояние нашего приложения Spring Boot. Также можно создать запуск запуска в Synology NAS, таким образом, ваше приложение будет запускаться всякий раз, когда ваша Synology перезагружается для их исправлений.
1
2
3
|
user @synology :/volume1/checkback/init.d$ ./checkback.sh status Running [ 18657 ] user @synology :/volume1/checkback/init.d$ |
Файл checkback.conf
содержит расположение нашего производственного конфигурационного файла, а также указывает папку журнала (вместо расположения по умолчанию / var / log)
1
2
3
4
|
bash- 4.3 # cat checkback.conf RUN_ARGS= "--spring.config.location=/volume1/checkback/synology-config.yml" LOG_FOLDER= "/volume1/checkback" bash- 4.3 # |
Теперь, когда у нас есть готовая структура, мы можем начать тестирование кода. Всякий раз, когда я занимаюсь разработкой приложения, мне бы хотелось, чтобы у него были тестовые данные или снимок производственных данных. Чтобы достичь этого, вы можете прочитать блог о поддельных данных Synology для JUnit Testing .
Теперь давайте начнем кодировать. Наше приложение использует файл YAML, чтобы определить, какую папку проверять на наличие квот и какие резервные наборы необходимо проверить. Они отображаются на @ConfigurationProperties
Spring. Конфиг выглядит так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
checkback: cron: '0 0 10 * * *' slack.channel: '#infra' quota-configs: - path: /volume1 excludePattern: '^@.*' backup-set-configs: - name: Mikrotik Backups uri: /volume1/backupftp/mikrotik_backup type: DISK file-set: - name: fe-prodnet01 export filterPattern: '.*fe-prodnet01-.*\.rsc' - name: fe-prodnet11 backup filterPattern: '.*fe-prodnet11.*\.backup' - name: Exchange Backups uri: /volume1/pex/backups type: DISK file-set: - name: Exchange psts filterPattern: '.*\.pst' groupByPattern: '.*\/backups\/(\d{4}-\d{2}-\d{2})\/' groupByPatternHasDatePattern: 'yyyy-MM-dd' deletePolicy: deleteEmptyDirectories: true |
Как видите, мы обновляем состояние каждый день в 10:00, оно определяется записью cron в YAML. Если есть какие-либо предупреждения, мы также опубликуем их на нашем канале Slack. Для этого мы используем jSlack , но существует множество других альтернатив.
Проверка квот
Чтобы проверить квоты, мы определили путь для проверки квот. По умолчанию мы исключаем каталоги, начинающиеся с «@», это каталоги, специфичные для Synology.
1
2
3
|
quota-configs: - path: /volume1 excludePattern: '^@.*' |
В Synology вы можете указать квоту для определенного общего файлового ресурса. Мы назовем эти жесткие квоты. Если вы не установили квоту (или забыли это сделать), мы по умолчанию установим квоту в 20 ГБ; это то, что мы будем называть мягкими квотами.
Чтобы проверить квоту в Synology, вы можете использовать команду btrfs
:
1
2
3
4
5
|
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
, квота не была установлена и по умолчанию будет 20 ГБ.
Следующий фрагмент кода Java выполняет эту команду и анализирует выходные данные.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 делать эту работу.
01
02
03
04
05
06
07
08
09
10
|
AtomicLong totalSize = new AtomicLong(); Files.walkFileTree(f, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { totalSize.addAndGet(Files.size(file)); return FileVisitResult.CONTINUE; } }); quotaStatus.used(totalSize.get()); |
Все, что осталось сделать, — это рассчитать оставшийся процент и отобразить его в индикаторе загрузки Bootstrap .
Форматирование байтов так, чтобы они были читаемы человеком, может быть сделано с помощью byteCountToDisplaySize из Apache Commons FileUtils . Тем не менее, этот метод плохо подходит для округления значений противоречивым способом.
В качестве альтернативы мы использовали byteunits и использовали его следующим образом, чтобы получить довольно необязательное двухточечное десятичное значение:
1
2
3
4
5
|
public class FileSizeUtil { public static String readableFileSize( long size) { return BinaryByteUnit.format(size, "#,##0.##" ); } } |
Если вы думаете, что мы закончили, вы забываете одно предупреждение. Чтобы выполнить команду brtfs
внутри приложения, вы должны быть пользователем root. К счастью, это приложение находится в нашей внутренней сети, и риск сделать это ограничен.
Пожалуйста, не запускайте приложения как root, если ваша Synology имеет общедоступное подключение к Интернету.
Чтобы запустить приложение Spring Boot от имени пользователя root, просто выберите файл от имени пользователя root . Spring Boot сделает все остальное за вас, потому что он всегда запускает приложение под пользователем, которому принадлежит файл jar .
1
|
bash- 4.3 # chown root:root checkback.jar |
Вы сделали! У нас все готово к проверке квот.
Вернитесь на следующей неделе, чтобы узнать, как контролировать наборы резервных копий.
Смотрите оригинальную статью здесь: Создание надежной системы резервного копирования
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |