自动数据库备份,备份后用sftp上传

This commit is contained in:
lvleigang 2024-10-22 14:33:30 +08:00
parent ed5d7fff69
commit c943cd82fb
7 changed files with 442 additions and 1 deletions

2
.gitignore vendored
View File

@ -64,3 +64,5 @@ $RECYCLE.BIN/
/base-common/target/
/base-core/target/
/base-webapp/target/classes/com/hzya/frame/
/fw-weixin/target/
/E:/yongansystem/log/2024-10-15/

View File

@ -0,0 +1,386 @@
package com.hzya.frame.plugin.BackUpDatabase.plugin;
import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.base.PluginBaseEntity;
import com.hzya.frame.web.entity.BaseResult;
import com.hzya.frame.web.entity.JsonResultEntity;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
/**
* 主数据模版(MdmModule)表服务接口
*
* @author makejava
* @since 2024-06-18 10:33:32
*/
public class BackUpDatabaseInitializer extends PluginBaseEntity {
Logger logger = LoggerFactory.getLogger(BackUpDatabaseInitializer.class);
@Override
public void initialize() {
logger.info(getPluginLabel() + "執行初始化方法initialize()");
}
@Override
public void destroy() {
logger.info(getPluginLabel() + "執行銷毀方法destroy()");
}
@Override
public String getPluginId() {
return "BackUpDatabasePlugin";
}
@Override
public String getPluginName() {
return "数据库备份下发";
}
@Override
public String getPluginLabel() {
return "BackUpDatabasePlugin";
}
@Override
public String getPluginType() {
return "1";
}
@Value("${database.filePase:}")
private String filePase;//文件保存路径
@Value("${database.fileName:data.sql}")
private String fileName;//文件保存名称
@Value("${database.databaseName:}")
private String databaseName;//库名
@Value("${database.host:}")
private String host;//地址
@Value("${database.port:}")
private String port;//端口
@Value("${database.username:}")
private String username;//用户名
@Value("${database.password:}")
private String password;//密码
@Value("${sftp.host:}")
private String sftpHost;
@Value("${sftp.port:}")
private Integer sftpPort;
@Value("${sftp.username:}")
private String sftpUsername;
@Value("${sftp.password:}")
private String sftpPassword;
@Value("${sftp.filePase:}")
private String sftpFilePase;
private ChannelSftp sftp = null;
private Session sshSession = null;
@Override
public JsonResultEntity executeBusiness(JSONObject requestJson) {
try {
if(filePase == null || "".equals(filePase)
|| databaseName == null || "".equals(databaseName)
|| fileName == null || "".equals(fileName)
|| host == null || "".equals(host)
|| port == null || "".equals(port)
|| username == null || "".equals(username)
|| password == null || "".equals(password)
){
return BaseResult.getSuccessMessageEntity("系统参数未配置不执行,数据库备份");
}
//查找是否存在当天数据库
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String data = sdf.format(new Date());
//当天路径
String nowDatabasePase = filePase + File.separator + data;
//不判断文件是否存在直接执行
if(!backFile(nowDatabasePase)){
return BaseResult.getFailureMessageEntity("备份失败");
}
//判断是否有sftp配置有的备份没有的不备份
if(sftpHost != null && !"".equals(sftpHost)
&& sftpPort != null && !"".equals(sftpPort)
&& sftpUsername != null && !"".equals(sftpUsername)
&& sftpPassword != null && !"".equals(sftpPassword)
&& sftpFilePase != null && !"".equals(sftpFilePase)
){
String sftpnowDatabasePase = sftpFilePase + File.separator + data;
if(!sendFile(nowDatabasePase,sftpnowDatabasePase)){
return BaseResult.getFailureMessageEntity("备份失败");
}
}
logger.info("执行成功");
return BaseResult.getSuccessMessageEntity("执行成功");
} catch (Exception e) {
logger.error("执行失败{}", e.getMessage());
return BaseResult.getFailureMessageEntity("备份失败");
}
}
private boolean backFile(String nowDatabasePase) {
try {
// 构建 mysqldump 命令
ProcessBuilder processBuilder = new ProcessBuilder(
"mysqldump",
"--ssl-mode=DISABLED",
"-h", host,
"-u", username,
"-p" + password,
"-P" + port,
databaseName);
// 启动进程并获取输入流
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
File f = creatFile(nowDatabasePase,fileName);
// 将备份内容写入文件
FileWriter writer = new FileWriter(f);
String line;
while ((line = reader.readLine())!= null) {
writer.write(line + "\n");
}
// 关闭资源
reader.close();
writer.close();
process.waitFor();
logger.info("文件备份成功路径:"+nowDatabasePase+ File.separator +fileName);
return true;
} catch (IOException | InterruptedException e) {
logger.info("文件备份失败:"+e.getMessage());
return false;
}
}
/**
* @Author lvleigang
* @Description 创建目录及文件
* @Date 8:59 上午 2024/10/22
* @param filePath
* @param fileName
* @return java.io.File
**/
public File creatFile(String filePath, String fileName) {
File folder = new File(filePath);
//文件夹路径不存在
if (!folder.exists()) {
boolean mkdirs = folder.mkdirs();
}
// 如果文件不存在就创建
File file = new File(filePath + File.separator + fileName);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
logger.error("创建备份文件失败:"+e.getMessage());
}
}
return file;
}
private boolean sendFile(String localFilePath,String remoteFileName) {
try {
connect();
uploadFile(remoteFileName,fileName,localFilePath,fileName);
disconnect();
return true;
} catch (Exception e) {
logger.error("sftp文件上传失败:"+e.getMessage());
return false;
}
}
public void connect() {
try {
JSch jsch = new JSch();
jsch.getSession(sftpUsername, sftpHost, sftpPort);
sshSession = jsch.getSession(sftpUsername, sftpHost, sftpPort);
if (logger.isInfoEnabled()) {
logger.info("Session created.");
}
sshSession.setPassword(sftpPassword);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
if (logger.isInfoEnabled()) {
logger.info("Session connected.");
}
Channel channel = sshSession.openChannel("sftp");
channel.connect();
if (logger.isInfoEnabled()) {
logger.info("Opening Channel.");
}
sftp = (ChannelSftp) channel;
if (logger.isInfoEnabled()) {
logger.info("Connected to " + host + ".");
}
} catch (Exception e) {
}
}
/**
* 关闭连接
*/
public void disconnect() {
if (this.sftp != null) {
if (this.sftp.isConnected()) {
this.sftp.disconnect();
if (logger.isInfoEnabled()) {
logger.info("sftp is closed already");
}
}
}
if (this.sshSession != null) {
if (this.sshSession.isConnected()) {
this.sshSession.disconnect();
if (logger.isInfoEnabled()) {
logger.info("sshSession is closed already");
}
}
}
}
/**
* 上传单个文件
*
* @param remotePath远程保存目录
* @param remoteFileName保存文件名
* @param localPath本地上传目录(以路径符号结束)
* @param localFileName上传的文件名
* @return
*/
public boolean uploadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
FileInputStream in = null;
try {
createDir(remotePath);
File file = new File(localPath + File.separator + localFileName);
in = new FileInputStream(file);
sftp.put(in, remoteFileName, 65536);
return true;
} catch (FileNotFoundException e) {
} catch (SftpException e) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return false;
}
/**
* 创建目录
*
* @param createpath
* @return
*/
public boolean createDir(String createpath) {
try {
if (isDirExist(createpath)) {
this.sftp.cd(createpath);
return true;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
this.sftp.cd(createpath);
return true;
} catch (SftpException e) {
}
return false;
}
/**
* 判断目录是否存在
*
* @param directory
* @return
*/
public boolean isDirExist(String directory) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* 如果目录不存在就创建目录
*
* @param path
*/
public void mkdirs(String path) {
File f = new File(path);
String fs = f.getParent();
f = new File(fs);
if (!f.exists()) {
f.mkdirs();
}
}
}

View File

@ -61,4 +61,22 @@ cbs8:
OA:
data_source_code: yc_oa
server:
port: 10086
port: 10086
# mysqldump -d mylm -hhzya.ufyct.com -p9096 -uroot -phzya1314 >%dirName%\table_view.sql
database:
databaseName: businesscenter
host: 192.168.2.237
port: 3306
username: root
password: hzya@1314
filePase: /Users/apple/Desktop/log
fileName: data.sql
#sftp:
# host: 192.168.2.237
# port: 9091
# username: cs237
# password: hzya@1314
# filePase: /databaseBack

View File

@ -126,3 +126,17 @@ jeecg :
bucketName: ??
data:
use: true
database:
databaseName:
host:
port:
username:
password:
filePase:
fileName:
sftp:
host:
port:
username:
password:
filePase:

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>BackUpDatabasePlugin</id>
<name>BackUpDatabasePlugin插件</name>
<category>20241021</category>
</plugin>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean name="backUpDatabaseInitializer" class="com.hzya.frame.plugin.BackUpDatabase.plugin.BackUpDatabaseInitializer" />
</beans>

10
pom.xml
View File

@ -406,6 +406,16 @@
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version> <!-- 这里的版本号可根据实际情况修改 -->
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
</dependencies>
<build>