feat: 数据库备份未完成
This commit is contained in:
parent
5d1b983c71
commit
8643220973
|
@ -6,8 +6,6 @@ import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@ -30,7 +28,4 @@ public class ScheduleExecuteLogDto {
|
||||||
@Schema(name = "triggerName", title = "触发器名称")
|
@Schema(name = "triggerName", title = "触发器名称")
|
||||||
private String triggerName;
|
private String triggerName;
|
||||||
|
|
||||||
@Schema(name = "endTime", title = "结束时间")
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 调度任务执行日志
|
* 调度任务执行日志
|
||||||
|
@ -45,9 +43,6 @@ public class ScheduleExecuteLog extends BaseEntity {
|
||||||
@Schema(name = "duration", title = "执行时间")
|
@Schema(name = "duration", title = "执行时间")
|
||||||
private Long duration;
|
private Long duration;
|
||||||
|
|
||||||
@Schema(name = "endTime", title = "结束时间")
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,5 @@ public class LocalDateTimeConstant {
|
||||||
public static final String YYYY_MM_DD = "yyyy-MM-dd";
|
public static final String YYYY_MM_DD = "yyyy-MM-dd";
|
||||||
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||||
public static final String YYYY_MM_DD_HH_MM_SS_SLASH = "yyyy/MM/dd HH:mm:ss";
|
public static final String YYYY_MM_DD_HH_MM_SS_SLASH = "yyyy/MM/dd HH:mm:ss";
|
||||||
public static final String YYYY_MM_DD_HH_MM_SS_UNDERLINE = "yyyy-MM-dd HH_mm_ss_SSS";
|
public static final String YYYY_MM_DD_HH_MM_SS_UNDERLINE = "yyyy_MM_dd_HH_mm_ss_SSS";
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import cn.bunny.dao.vo.common.BaseVo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -35,7 +33,4 @@ public class QuartzExecuteLogVo extends BaseVo {
|
||||||
@Schema(name = "duration", title = "执行时间")
|
@Schema(name = "duration", title = "执行时间")
|
||||||
private Integer duration;
|
private Integer duration;
|
||||||
|
|
||||||
@Schema(name = "endTime", title = "结束时间")
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ COPY target/*.jar /home/server/app.jar
|
||||||
VOLUME /usr/bin/docker
|
VOLUME /usr/bin/docker
|
||||||
VOLUME ["/var/run/docker.sock"]
|
VOLUME ["/var/run/docker.sock"]
|
||||||
VOLUME /etc/docker/daemon.json
|
VOLUME /etc/docker/daemon.json
|
||||||
VOLUME ["/bunny/docker_data/mysql/slave_3304/backup"]
|
VOLUME ["/home/backup"]
|
||||||
|
|
||||||
# 启动容器时的进程
|
# 启动容器时的进程
|
||||||
ENTRYPOINT ["java","-jar","/home/server/app.jar"]
|
ENTRYPOINT ["java","-jar","/home/server/app.jar"]
|
||||||
|
|
|
@ -65,14 +65,14 @@ public class SchedulersController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "暂停任务", description = "暂停任务")
|
@Operation(summary = "暂停任务", description = "暂停任务")
|
||||||
@PutMapping("/pauseScheduler")
|
@PutMapping("/pauseSchedulers")
|
||||||
public Result<String> pause(@RequestBody SchedulersOperationDto dto) {
|
public Result<String> pause(@RequestBody SchedulersOperationDto dto) {
|
||||||
schedulersService.pauseScheduler(dto);
|
schedulersService.pauseScheduler(dto);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "恢复任务", description = "恢复任务")
|
@Operation(summary = "恢复任务", description = "恢复任务")
|
||||||
@PutMapping("/resumeScheduler")
|
@PutMapping("/resumeSchedulers")
|
||||||
public Result<String> resume(@RequestBody SchedulersOperationDto dto) {
|
public Result<String> resume(@RequestBody SchedulersOperationDto dto) {
|
||||||
schedulersService.resumeScheduler(dto);
|
schedulersService.resumeScheduler(dto);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
package cn.bunny.services.quartz;
|
package cn.bunny.services.quartz;
|
||||||
|
|
||||||
import cn.bunny.dao.pojo.constant.LocalDateTimeConstant;
|
|
||||||
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
import cn.bunny.services.aop.annotation.QuartzSchedulers;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobDataMap;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.quartz.Scheduler;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.repository.init.ResourceReader;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.time.LocalDateTime;
|
import java.io.InputStreamReader;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -18,46 +25,47 @@ import java.time.format.DateTimeFormatter;
|
||||||
@Component
|
@Component
|
||||||
public class DatabaseBackupJob implements Job {
|
public class DatabaseBackupJob implements Job {
|
||||||
|
|
||||||
@Value("${spring.datasource.dynamic.datasource.master.username}")
|
@Autowired
|
||||||
private String masterUsername;
|
private Scheduler scheduler;
|
||||||
|
|
||||||
@Value("${spring.datasource.dynamic.datasource.master.password}")
|
|
||||||
private String masterPassword;
|
|
||||||
|
|
||||||
@Value("${bunny.master.database}")
|
|
||||||
private String masterDatabase;
|
|
||||||
|
|
||||||
@Value("${bunny.master.databaseBackupDir}")
|
|
||||||
private String databaseBackupDir;
|
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext context) {
|
public void execute(JobExecutionContext context) {
|
||||||
// 格式化时间
|
InputStream inputStream = ResourceReader.class.getResourceAsStream("static/backup.sh");
|
||||||
LocalDateTime localStartExecuteTime = LocalDateTime.now();
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||||
DateTimeFormatter sqlTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_UNDERLINE);
|
String line;
|
||||||
String sqlTimeNow = localStartExecuteTime.format(sqlTimeFormatter);
|
while ((line = reader.readLine()) != null) {
|
||||||
|
System.out.println(line);
|
||||||
// 命令行参数
|
|
||||||
String dockerCommand = "docker exec -it bunny_auth_server bash";
|
|
||||||
String mysqldumpCommand = "mysqldump -u " + masterUsername + " -p" + masterPassword + " " + masterDatabase + " > " + databaseBackupDir + "backup_auth_admin_" + sqlTimeNow + ".sql";
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(dockerCommand, mysqldumpCommand);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 执行命令
|
|
||||||
Process process = processBuilder.start();
|
|
||||||
|
|
||||||
// 执行后读取内容
|
|
||||||
InputStream inputStream = process.getInputStream();
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
byte[] bytes = new byte[1024];
|
|
||||||
int bytesRead;
|
|
||||||
|
|
||||||
while ((bytesRead = inputStream.read(bytes)) != -1) {
|
|
||||||
output.append(new String(bytes, 0, bytesRead));
|
|
||||||
}
|
|
||||||
System.out.println(output);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
throw new RuntimeException(exception);
|
|
||||||
}
|
}
|
||||||
|
// 执行脚本
|
||||||
|
String scriptPath = Objects.requireNonNull(getClass().getClassLoader().getResource("static/backup.sh")).getPath();
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder("bash", scriptPath);
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
ProcessHandle handle = process.toHandle();
|
||||||
|
|
||||||
|
// 执行任务的pid
|
||||||
|
long pid = handle.pid();
|
||||||
|
|
||||||
|
// 执行任务系统信息
|
||||||
|
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
|
||||||
|
Map<String, String> environment = processBuilder.environment();
|
||||||
|
String info = handle.info().toString();
|
||||||
|
jobDataMap.put("pid", pid);
|
||||||
|
jobDataMap.put("systemInfo", info);
|
||||||
|
jobDataMap.put("environment", environment);
|
||||||
|
|
||||||
|
// 进程是否结束
|
||||||
|
if (process.waitFor(5, TimeUnit.MINUTES)) {
|
||||||
|
int waitedFor = process.waitFor();
|
||||||
|
jobDataMap.put("existCode", waitedFor);
|
||||||
|
} else process.destroyForcibly();
|
||||||
|
|
||||||
|
// // 执行后读取内容
|
||||||
|
// BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
// String line;
|
||||||
|
// while ((line = reader.readLine()) != null) {System.out.println(line);}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@ import jakarta.validation.Valid;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -76,7 +74,6 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
||||||
* @return 所有调度任务内容
|
* @return 所有调度任务内容
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(cacheNames = "schedulers", key = "'allSchedulers'", cacheManager = "cacheManagerWithMouth")
|
|
||||||
public List<Map<String, String>> getAllScheduleJobList() {
|
public List<Map<String, String>> getAllScheduleJobList() {
|
||||||
Set<Class<?>> classesWithAnnotation = annotationScanner.getClassesWithAnnotation(QuartzSchedulers.class);
|
Set<Class<?>> classesWithAnnotation = annotationScanner.getClassesWithAnnotation(QuartzSchedulers.class);
|
||||||
return classesWithAnnotation.stream().map(cls -> {
|
return classesWithAnnotation.stream().map(cls -> {
|
||||||
|
@ -103,7 +100,6 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
// @CacheEvict(cacheNames = "schedulers", key = "'allSchedulers'", beforeInvocation = true)
|
|
||||||
public void addSchedulers(@Valid SchedulersAddDto dto) {
|
public void addSchedulers(@Valid SchedulersAddDto dto) {
|
||||||
String jobName = dto.getJobName();
|
String jobName = dto.getJobName();
|
||||||
String jobGroup = dto.getJobGroup();
|
String jobGroup = dto.getJobGroup();
|
||||||
|
@ -179,7 +175,6 @@ public class SchedulersServiceImpl extends ServiceImpl<SchedulersMapper, Schedul
|
||||||
* @param dto Schedulers公共操作表单
|
* @param dto Schedulers公共操作表单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = "schedulers", key = "'allSchedulers'", beforeInvocation = true)
|
|
||||||
public void deleteSchedulers(SchedulersOperationDto dto) {
|
public void deleteSchedulers(SchedulersOperationDto dto) {
|
||||||
try {
|
try {
|
||||||
String jobGroup = dto.getJobGroup();
|
String jobGroup = dto.getJobGroup();
|
||||||
|
|
|
@ -46,7 +46,6 @@ bunny:
|
||||||
database: auth_admin
|
database: auth_admin
|
||||||
username: root
|
username: root
|
||||||
password: "02120212"
|
password: "02120212"
|
||||||
databaseBackupDir: "/home/backup/"
|
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
host: 192.168.3.98
|
host: 192.168.3.98
|
||||||
|
|
|
@ -32,7 +32,6 @@ bunny:
|
||||||
database: auth_admin
|
database: auth_admin
|
||||||
username: root
|
username: root
|
||||||
password: "02120212"
|
password: "02120212"
|
||||||
databaseBackupDir: "/home/backup/"
|
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
host: 47.120.65.66
|
host: 47.120.65.66
|
||||||
|
|
|
@ -17,12 +17,11 @@
|
||||||
<id column="trigger_name" property="triggerName"/>
|
<id column="trigger_name" property="triggerName"/>
|
||||||
<id column="execute_result" property="executeResult"/>
|
<id column="execute_result" property="executeResult"/>
|
||||||
<id column="duration" property="duration"/>
|
<id column="duration" property="duration"/>
|
||||||
<id column="end_time" property="endTime"/>
|
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<!-- 通用查询结果列 -->
|
<!-- 通用查询结果列 -->
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, create_time, update_time, create_user, update_user, is_deleted, job_name, job_group, job_class_name, cron_expression, trigger_name, execute_result, duration, end_time
|
id, create_time, update_time, create_user, update_user, is_deleted, job_name, job_group, job_class_name, cron_expression, trigger_name, execute_result, duration
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<!-- 分页查询调度任务执行日志内容 -->
|
<!-- 分页查询调度任务执行日志内容 -->
|
||||||
|
@ -46,9 +45,6 @@
|
||||||
<if test="dto.triggerName != null and dto.triggerName != ''">
|
<if test="dto.triggerName != null and dto.triggerName != ''">
|
||||||
and trigger_name like CONCAT('%',#{dto.triggerName},'%')
|
and trigger_name like CONCAT('%',#{dto.triggerName},'%')
|
||||||
</if>
|
</if>
|
||||||
<if test="dto.endTime != null and dto.endTime != ''">
|
|
||||||
and end_time like CONCAT('%',#{dto.endTime},'%')
|
|
||||||
</if>
|
|
||||||
</where>
|
</where>
|
||||||
order by update_time desc
|
order by update_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 设置备份文件存放目录
|
||||||
|
backup_dir="/home/backup/"
|
||||||
|
|
||||||
|
# 获取当前时间并格式化为 yyyy_MM_dd_HH_mm_ss_SSS 格式
|
||||||
|
timestamp=$(date +"%Y_%m_%d_%H_%M_%S_%3N")
|
||||||
|
|
||||||
|
# 设置数据库用户名、密码和数据库名
|
||||||
|
db_user="root"
|
||||||
|
db_pass="02120212"
|
||||||
|
db_name="auth_admin"
|
||||||
|
|
||||||
|
# 设置备份文件名
|
||||||
|
backup_file="${backup_dir}backup_${db_name}_${timestamp}.sql"
|
||||||
|
|
||||||
|
# 执行备份命令
|
||||||
|
docker exec -it slave_3304 bash -c "mysqldump -u ${db_user} -p${db_pass} ${db_name} > ${backup_file}"
|
||||||
|
|
||||||
|
# 输出备份文件路径
|
||||||
|
echo "Backup completed: ${backup_file}"
|
|
@ -0,0 +1,48 @@
|
||||||
|
package cn.bunny.service;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.data.redis.core.script.ScriptExecutor;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class TestPath {
|
||||||
|
@SneakyThrows
|
||||||
|
@Test
|
||||||
|
void testPath() {
|
||||||
|
String scriptPath = Objects.requireNonNull(getClass().getClassLoader().getResource("static/backup.sh")).getPath();
|
||||||
|
String path = ScriptExecutor.class.getClassLoader().getResource("static/backup.sh").getPath();
|
||||||
|
System.out.println(path);
|
||||||
|
// 执行脚本
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder("bash", scriptPath);
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
|
||||||
|
// 执行后读取内容
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {System.out.println(line);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Test
|
||||||
|
void test2() {
|
||||||
|
ClassLoader classLoader = ResourceLoader.class.getClassLoader();
|
||||||
|
InputStream inputStream = classLoader.getResourceAsStream("static/backup.sh");
|
||||||
|
try (java.util.Scanner s = new java.util.Scanner(inputStream)) {
|
||||||
|
while (s.hasNext()) {
|
||||||
|
System.out.println(s.nextLine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte[] bytes = inputStream.readAllBytes();
|
||||||
|
String string = new String(bytes, StandardCharsets.UTF_8);
|
||||||
|
System.out.println(string);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue