小網(wǎng)站如何做密碼找回福州seo網(wǎng)絡(luò)推廣
NBlog部署維護(hù)流程記錄(持續(xù)更新):https://blog.csdn.net/qq_43349112/article/details/136129806
為了避免服務(wù)器被攻擊,給博客添加了一個(gè)MySQL數(shù)據(jù)備份功能。
此功能是配合博客寫(xiě)的,有些方法直接用的已有的,不會(huì)再詳細(xì)展示代碼。
備份大致功能步驟如下:
- 使用mysqldump備份數(shù)據(jù)(完成)
- 對(duì)備份文件進(jìn)行壓縮(完成)
- 壓縮文件上傳到OSS(完成)
- 文件清理(完成)
- 郵件通知(TODO)
- 適應(yīng)化改造(TODO)
詳細(xì)步驟見(jiàn)下文
0.備份任務(wù)主邏輯
目前暫時(shí)使用定時(shí)任務(wù)觸發(fā),以下僅為核心代碼。
/*** 定時(shí)任務(wù),每周一凌晨四點(diǎn),備份MySQL的數(shù)據(jù)* 備份邏輯:* 1.mysql數(shù)據(jù)備份到文件* 2.備份文件壓縮* 3.壓縮文件上傳到OSS* 4.殘留文件清理* 5.備份結(jié)果的郵件通知 //TODO* 6.適應(yīng)化改造,改成類似NBlog中的定時(shí)任務(wù) //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備份開(kāi)始");// 1.mysql數(shù)據(jù)備份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數(shù)據(jù)備份失敗");log.error(e.getMessage());}}
1.mysqldump備份
通過(guò)Runtime.getRuntime().exec(xxx)
執(zhí)行備份命令,保存到指定路徑下。
由于我的MySQL
是docker
部署,因此使用了docker exec
命令。
命令的執(zhí)行結(jié)果會(huì)比較長(zhǎng),日志級(jí)別建議低一些,下面用的debug
級(jí)別。
需要注意exec(cmds)
的參數(shù)格式,寫(xiě)錯(cuò)的話命令不會(huì)執(zhí)行并且不報(bào)錯(cuò),排查了半個(gè)下午。
/*** MySQL數(shù)據(jù)備份* @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("欲執(zhí)行命令:{}", 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備份命令執(zhí)行成功,耗時(shí):{}ms", end - start);}
2.備份文件壓縮
壓縮成zip格式,核心代碼如下:
* 壓縮文件到指定路徑* @param oriFilePath 要壓縮的原文件路徑* @param compressedFilePath 壓縮后的文件存放路徑* @throws IOException IO異常,不在catch模塊捕捉,交給調(diào)用方自行處理*/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.清除殘留文件
上傳后,備份文件和壓縮文件已經(jīng)無(wú)用,刪除掉即可:
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.郵件通知結(jié)果(TODO)
6.適應(yīng)化改造(TODO)
NBlog
定時(shí)任務(wù)可以在前端配置,自由修改觸發(fā)時(shí)間,并且可以直接觸發(fā)。
目前的暫時(shí)寫(xiě)死了,下周改造下。
X、測(cè)試
確定定時(shí)任務(wù)觸發(fā)后,OSS
能看到文件即可