服务器数据库定期自动备份到本地

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iuie_sl/article/details/82082907

应用场景

 服务器上的数据库上的信息可以通过cron实现在服务器上的定时备份,但是如果服务器被攻击导致整个服务器上的数据无法还原,重要的信息将被丢失。所有需要一个定期自动将服务器上的MySQL的数据备份到本地。

大概思路

1. 通过Spring Quart编写一个定时任务,使用mysqldump备份服务器上的数据库,发送数据库的备份结果到RabbitMQ,在Windows客户端 监听消息,将接受到数据库备份结果保存到本地。

2. 一些附加的功能。在服务端使用swagger页面来管理任务,比如修改任务的cron表达式。暂停任务,重新开启任务,查询任务状态。使用jenkins自动build,run修改的代码,实现自动发布。在客户端实现开机自启。

项目使用的技术包括: SpringBoot, Swagger, SpringQuartz, RabbitMQ。

核心代码

Linux环境下备份MySQL的代码

@Service("linuxBackMySQLServiceImpl")
public class LinuxBackMySQLServiceImpl implements BackMySQLService {

    private static Logger log = LoggerFactory.getLogger(LinuxBackMySQLServiceImpl.class);
    /**
     * linux实现远程备份
     * @throws IOException
     */
    @Override
    public void exportDatabaseTool() throws Exception {
        String[] commend = new String[] {"/bin/sh", "-c", "mysqldump -h "+ConstantUtil.getHostIp()+" -P"+ConstantUtil.getPort()+" -u"+ ConstantUtil.getUserName()+" -p" +ConstantUtil.getPassword() +  " --opt --default-character-set=utf8mb4 --routines " + ConstantUtil.getDatabaseName() + ">" +ConstantUtil.getFileName()};
        log.info("commend————————————————————————————————"+commend);
        ShellUtils.executeLinuxCommand(commend);
    }
}

public static String executeLinuxCommand(String[] command) throws Exception{
        Runtime runtime = Runtime.getRuntime();
        Process pro = runtime.exec(command);

        // 等待执行完成
        int status = pro.waitFor();
        if (status != 0) {
            log.info("Failed to call shell's command");
        }
        // 获取并打印日志
        BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
        StringBuffer strbr = new StringBuffer();
        String line;
        while ((line = br.readLine())!= null) {
            strbr.append(line).append("\n");
        }
        return strbr.toString();
    }

Windows环境下备份MySQL的代码

@Service("windwosBackMySQLServiceImpl")
public class WindwosBackMySQLServiceImpl implements BackMySQLService {


    @Override
    public void exportDatabaseTool() throws Exception {
        String commend = "cmd /c D:\\mysqldump -u"+ConstantUtil.getUserName()+" -p" +ConstantUtil.getPassword() +  " --opt --default-character-set=utf8mb4 --routines " + ConstantUtil.getDatabaseName() + ">" +ConstantUtil.getFileName();
        ShellUtils.executeCommand(commend);
    }


}

任务类

public class BackMySQLTask implements BaseJob {

    private static Logger log = LoggerFactory.getLogger(BackMySQLTask.class);

    private AmqpTemplate rabbitTemplate;

    private BackMySQLService backMySQLService;

    private void init() {
        String osName = System.getProperty("os.name");
        if(StringUtils.startsWithIgnoreCase(osName, "Windows")){
            backMySQLService = ApplicationContextProvider.getBean(WindwosBackMySQLServiceImpl.class);
        }else if (StringUtils.startsWithIgnoreCase(osName, "Linux")) {
            backMySQLService = ApplicationContextProvider.getBean(LinuxBackMySQLServiceImpl.class);
        } else {
            throw new RuntimeException("未知的系统!");
        }
        rabbitTemplate = ApplicationContextProvider.getBean(AmqpTemplate.class);
    }

    @Override
    public void execute(JobExecutionContext context) {
        try {
            if(backMySQLService == null || rabbitTemplate == null){
                init();
            }
            System.out.println("开始执行任务");
            //1. 执行备份数据
            backMySQLService.exportDatabaseTool();
            //2. 给rabbitmq发送消息
            Map<String, String> message = new HashMap<String, String>();
            message.put("backupMysql", FileChangeString());
            rabbitTemplate.convertAndSend("black", message);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private String FileChangeString() throws Exception {
        File file = new File(ConstantUtil.getFileName());
        InputStream in = new FileInputStream(file);
        int flen = (int) file.length();
        byte[] strBuffer = new byte[flen];
        in.read(strBuffer, 0, flen);
        file.delete();
        return new String(strBuffer);
    }
}

客户端也使用的springBoot项目,实现SpringBoot项目在Windows上的后台自动启动使用的是AlwaysUp。在Linux的后台启动只需用&,Windows上不行

 
 
 Name : 取一个名字
 Application: 把项目的启动命令写到一个bat文件中
 

设置AlwaysUp的开机自启,开机后SpringBoot项目就在后台启动了。

安装和破解AlwaysUp
http://www.xue51.com/soft/6072.html#wypl

具体代码下载

https://download.csdn.net/download/iuie_sl/10627790

猜你喜欢

转载自blog.csdn.net/iuie_sl/article/details/82082907