应用场景
服务器上的数据库上的信息可以通过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
具体代码下载