杜洪波
4 天以前 b3c04038def5b4c248db1441eaacf84bbf153aff
系统备份优化,输出文件改为UTF-8格式
已修改1个文件
86 ■■■■ 文件已修改
src/main/java/com/product/system/backup/service/SystemBackupService.java 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/system/backup/service/SystemBackupService.java
@@ -59,6 +59,7 @@
     *     调用地点:定时任务配置功能(bean)
     */
    public void systemBackupInit(){
        // 初始日志文件
        log = new BackupLogger();
        // 在日志中记录操作系统信息,便于调试
        log.writeInfo("【系统备份入口】操作系统: " + System.getProperty("os.name"), BackupLogger.INFO_TYPE);
@@ -68,6 +69,7 @@
        NUMBER_DATE = numberDateFormat.format(new Date());
        log.writeInfo("【系统备份入口】系统日期:" + NUMBER_DATE, BackupLogger.INFO_TYPE);
        log.writeInfo("【系统备份入口】系统时间:" + NUMBER_TIME, BackupLogger.INFO_TYPE);
        // 进入备份进程
        backupProcess();
        log.closeLogger();
    }
@@ -87,13 +89,12 @@
        status = runExpDataBase();
        if (!status)
            return;
        // 第三步:执行对数据库文件、工程代码、上传文件做压缩备份
        status = zipDataBackup();
        if (!status)
            return;
        // 第四步:上传压缩备份文件到FTP
        status = uploadBackupMachine();
        status = sftpTransferService(true);
//        uploadBackupMachine2();
        if (!status)
            return;
@@ -111,6 +112,9 @@
    public boolean initSystemConfig() {
        log.writeInfo("【初始配置文件】开始初始系统配置文件..................", BackupLogger.INFO_TYPE);
        try (InputStream  reader = getClass().getClassLoader().getResourceAsStream(CONFIG_FILE_PATH)) {
            if (reader == null) {
                log.writeInfo("【初始配置文件】初始系统配置文件失败:" + CONFIG_FILE_PATH + "配置文件不存在", BackupLogger.ERROR_TYPE);
            }
            // 读取备份配置文件
            config = new Properties();
            config.load(reader);
@@ -178,7 +182,7 @@
        try {
            Process process = processBuilder.start();
            // 读取mysqldump的输出并写入到备份文件
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
                 FileWriter writer = new FileWriter(backupFile)) {
                
                String line;
@@ -199,6 +203,10 @@
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.writeInfo("【备份数据库】数据库备份成功:" + backupFile.getAbsolutePath(), BackupLogger.INFO_TYPE);
//              if (!"127.0.0.1".equals(databaseHost)) {
                    // 获取数据库备份文件
//                    return sftpTransferService(false);
//                }
            } else {
                log.writeInfo("【备份数据库】数据库备份失败,退出码: " + exitCode, BackupLogger.ERROR_TYPE);
            }
@@ -270,26 +278,39 @@
    }
    
    /**
     *     第四步:SFTP发送上传备用机
     * SFTP连接:通过SFTP将备份文件上传备用机  或  从mysql服务器上获取备份文件
     * @param isUpload     是否上传
     * @return
     */
    public boolean uploadBackupMachine() {
        log.writeInfo("【上传备份文件】开始上传备份文件..................", BackupLogger.INFO_TYPE);
        String localFile = config.getProperty("ZIPFILE_BACKUP"); // 本地文件路径
        String remotePath = config.getProperty("UPLOAD_BACKUP_DIR") + NUMBER_TIME + ".zip"; // 远程文件路径
        int port = Integer.valueOf(config.getProperty("UPLOAD_SFTP_PORT")); //SSH端口
        String host = config.getProperty("UPLOAD_SFTP_HOST"); // 备用服务器的IP地址
        String user = config.getProperty("UPLOAD_SFTP_USER"); // 备用服务器的用户名
        String password = config.getProperty("UPLOAD_SFTP_PWD"); // 备用服务器的密码
        log.writeInfo("【上传备份文件】上传备用机地址:" + host, BackupLogger.INFO_TYPE);
        log.writeInfo("【上传备份文件】上传备用机端口:" + port, BackupLogger.INFO_TYPE);
        log.writeInfo("【上传备份文件】上传备用机目录:" + remotePath, BackupLogger.INFO_TYPE);
        if (StringUtils.isEmpty(host) || StringUtils.isEmpty(user) || StringUtils.isEmpty(password)) {
            log.writeInfo("【上传备份文件】上传备用机地址SFTP信息未配置完整,不予上传", BackupLogger.INFO_TYPE);
    public boolean sftpTransferService(boolean isUpload) {
        String sftpTitle = null;
        String localFilePath = null;
        String sftpFilePath = null;
        if(isUpload) {
            sftpTitle = "上传系统备份文件";
            localFilePath = config.getProperty("ZIPFILE_BACKUP"); // 本地文件路径
            sftpFilePath = config.getProperty("UPLOAD_BACKUP_DIR") + NUMBER_TIME + ".zip"; // SFTP服务文件路径
        } else {
//            sftpTitle = "获取数据库备份文件";
//            localFilePath = config.getProperty("DATABASE_BACKUP"); // 本地文件路径
//            sftpFilePath = config.getProperty("DATABASE_BACKUP"); // SFTP服务文件路径
        }
        String host = config.getProperty("UPLOAD_SFTP_HOST"); // SFTP服务IP地址
        String port = config.getProperty("UPLOAD_SFTP_PORT"); // SSH端口
        String user = config.getProperty("UPLOAD_SFTP_USER"); // SFTP服务的用户名
        String password = config.getProperty("UPLOAD_SFTP_PWD"); // SFTP服务的密码
        log.writeInfo(String.format("【%s】开始%s..................", sftpTitle, sftpTitle), BackupLogger.INFO_TYPE);
        log.writeInfo(String.format("【%s】SFTP服务地址:", sftpTitle) + host, BackupLogger.INFO_TYPE);
        log.writeInfo(String.format("【%s】SFTP服务端口:", sftpTitle) + port, BackupLogger.INFO_TYPE);
        log.writeInfo(String.format("【%s】SFTP服务存储目录:", sftpTitle) + sftpFilePath, BackupLogger.INFO_TYPE);
        log.writeInfo(String.format("【%s】当前服务存储目录:", sftpTitle) + localFilePath, BackupLogger.INFO_TYPE);
        if (StringUtils.isEmpty(host) || StringUtils.isEmpty(port) || StringUtils.isEmpty(user) || StringUtils.isEmpty(password)) {
            log.writeInfo(String.format("【%s】SFTP信息未配置完整,不予连接传输文件", sftpTitle), BackupLogger.INFO_TYPE);
            return true;
        }
        try {
             JSch jsch = new JSch();
             Session session = jsch.getSession(user, host, port);
            Session session = jsch.getSession(user, host, Integer.valueOf(port));
             session.setPassword(password);
             session.setConfig("StrictHostKeyChecking", "no"); // 仅限测试环境
             session.connect(5000); // 设置连接超时时间
@@ -298,26 +319,41 @@
             channel.connect(5000); // 设置通道超时时间
             ChannelSftp sftpChannel = (ChannelSftp) channel;
             
             // 确保远程目录存在(关键步骤)
             String remoteDir = remotePath.substring(0, remotePath.lastIndexOf('/'));
            // 确保目录存在(关键步骤)
            String remoteDir = sftpFilePath.substring(0, sftpFilePath.lastIndexOf('/'));
             if (!remoteDir.startsWith("/")) {
                 remoteDir = "/" + remoteDir;
             }
            if(isUpload) {
             // 创建对应目录文件夹
             createRemoteDirectory(sftpChannel, remoteDir);
             sftpChannel.put(localFile, remotePath, new SftpProgressMonitor() {
                sftpChannel.put(localFilePath, sftpFilePath, new SftpProgressMonitor() {
                 public void init(int op, String src, String dest, long max) {
                     log.writeInfo("【上传备份文件】开始传输: " + src + " -> " + dest, BackupLogger.INFO_TYPE);
                        log.writeInfo("【上传系统备份文件】开始传输: " + src + " -> " + dest, BackupLogger.INFO_TYPE);
                 }
                 public boolean count(long count) { return true; }
                 public void end() { log.writeInfo("【上传备份文件】传输完成", BackupLogger.INFO_TYPE); }
                    public void end() { log.writeInfo("【上传系统备份文件】传输完成", BackupLogger.INFO_TYPE); }
             });
            } else {
                // 创建对应目录文件夹
                File fileDirectory = new File(remoteDir);
                if (!fileDirectory.exists()) {
                    fileDirectory.mkdirs();
                }
                sftpChannel.get(localFilePath, sftpFilePath, new SftpProgressMonitor() {
                    public void init(int op, String src, String dest, long max) {
                        log.writeInfo("【获取数据库备份文件】开始传输: " + src + " -> " + dest, BackupLogger.INFO_TYPE);
                    }
                    public boolean count(long count) { return true; }
                    public void end() { log.writeInfo("【获取数据库备份文件】传输完成", BackupLogger.INFO_TYPE); }
                });
            }
            sftpChannel.exit();
            session.disconnect();
            log.writeInfo("【上传备份文件】上传备份文件成功", BackupLogger.INFO_TYPE);
            log.writeInfo(String.format("【%s】%s成功", sftpTitle, sftpTitle), BackupLogger.INFO_TYPE);
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
            log.writeInfo("【上传备份文件】上传备份文件失败:" + e.getMessage(), BackupLogger.ERROR_TYPE);
            log.writeInfo(String.format("【%s】%s失败:", sftpTitle, sftpTitle) + e.getMessage(), BackupLogger.ERROR_TYPE);
            return false;
        }
        return true;