Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinBlandy committed Jan 27, 2022
1 parent 348bc58 commit b633d33
Show file tree
Hide file tree
Showing 16 changed files with 407 additions and 8 deletions.
217 changes: 217 additions & 0 deletions Codings/BackupService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package org.sobyte.service;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.io.FileUtils;
import org.sobyte.constant.SystemConstant;
import org.sobyte.model.dto.BackupFileDTO;
import org.sobyte.utils.ZipUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zaxxer.hikari.HikariDataSource;

import lombok.extern.slf4j.Slf4j;

/**
*
*
* 数据备份服务
*
* @author KevinBlandy
*
*/
@Service
@Slf4j
public class BackupService {

public static final DateTimeFormatter BACK_UP_FILE_NAME_FORMATTER = DateTimeFormatter
.ofPattern("yyyyMMddHHmmssSSS");

@Autowired
private HikariDataSource hikariDataSource;

/**
* 读取缓存的文件列表
*
* @return
* @throws IOException
*/
public List<BackupFileDTO> list() throws IOException {

if (Files.notExists(SystemConstant.BACK_PATH)) {
return List.of();
}

return Files.list(SystemConstant.BACK_PATH).filter(file -> !Files.isDirectory(file)).sorted((p1, p2) -> {
try {
return Files.readAttributes(p1, BasicFileAttributes.class).creationTime()
.compareTo(Files.readAttributes(p2, BasicFileAttributes.class).creationTime());
} catch (IOException e) {
throw new RuntimeException(e);
}
}).map(file -> {
try {
return BackupFileDTO.builder().name(file.getFileName().toString())
.creatAt(LocalDateTime.ofInstant(
Files.readAttributes(file, BasicFileAttributes.class).creationTime().toInstant(),
ZoneId.systemDefault()))
.build();
} catch (IOException e) {
throw new RuntimeException(e);
}
}).toList();
}

/*
* /backup
*
*/
/**
*
* 执行文件备份操作
*
* @throws IOException
*/
public void backup() throws IOException {
// 创建临时工作目录
Path tempDir = Files.createDirectories(SystemConstant.BACK_PATH.resolve("temp"));
try {
log.info("压缩资源文件...");

/**
* 压缩资源文件
*/
Path publicFile = ZipUtils.zip(SystemConstant.UPLOAD_PATH.getParent(), tempDir.resolve("public.zip"));

log.info("资源文件压缩完毕: {}", publicFile);

/**
* SQL资源文件导出 !!!只能导出本地MYSQL服务器上的数据,如果MYSQL服务器在其他机器,则会执行失败
*/
Path sqlFile = tempDir.resolve("db.sql");

mysqlDump(sqlFile);

if (!Files.exists(sqlFile)) {
// SQL导出失败的情况下, 创建空文件
Files.createFile(sqlFile);
}

Path backUpFile = SystemConstant.BACK_PATH
.resolve("backup-" + BACK_UP_FILE_NAME_FORMATTER.format(LocalDateTime.now()) + ".zip");

log.info("打包文件: {}", backUpFile);

ZipUtils.zip(new Path[] { publicFile, sqlFile }, backUpFile);

log.info("备份成功");
} finally {
// 清空工作目录
FileUtils.cleanDirectory(tempDir.toFile());
}
}

/**
* 导出SQL文件
*
* @param file 导出的SQL文件
*/
private void mysqlDump(Path file) {

// 获取当前数据库名称
String database = null;

try (Connection connection = hikariDataSource.getConnection()) {
try (ResultSet resultSet = connection.createStatement().executeQuery("SELECT DATABASE();")) {
if (resultSet.next()) {
database = resultSet.getString(1);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}

ByteArrayOutputStream stdErr = new ByteArrayOutputStream();

try (OutputStream stdOut = new BufferedOutputStream(Files.newOutputStream(file, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING))) {

DefaultExecutor defaultExecutor = new DefaultExecutor();
defaultExecutor.setWatchdog(new ExecuteWatchdog(TimeUnit.MINUTES.toMillis(10))); // 超时时间,10分钟
defaultExecutor.setStreamHandler(new PumpStreamHandler(stdOut, stdErr));

CommandLine commandLine = new CommandLine("mysqldump");
commandLine.addArgument("-u" + hikariDataSource.getUsername()); // 用户名
commandLine.addArgument("-p" + hikariDataSource.getPassword()); // 密码
commandLine.addArgument(database);

log.info("导出SQL数据...");

// 同步执行,返回执行结果
int exitCode = defaultExecutor.execute(commandLine);

// 异步执行
// DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
// defaultExecutor.execute(commandLine, resultHandler);
//
// // 阻塞,直到执行完毕
// resultHandler.waitFor();

log.info("SQL数据导出完毕: exitCode={}, sqlFile={}", exitCode, file.toString());

} catch (Exception e) {
log.error("SQL数据导出异常: {}", e.getMessage());
log.error("std err: {}{}", System.lineSeparator(), stdErr.toString());
}
}

/**
* 从PATH中解析出可执行文件的绝对路径
*
* @param execute
* @return
*/
// protected String lockPath(String execute) {
// // 从path中解析可执行文件的绝对路径
// String path = System.getenv("PATH");
//
// String separator = System.getProperty("path.separator");
//
// String[] suffixs = null;
//
// if (SystemUtils.IS_OS_WINDOWS) {
// suffixs = new String[] { ".exe", ".bat", ".cmd" };
// } else {
// suffixs = new String[] { "" };
// }
//
// for (String dir : path.split(separator)) {
// for (String suffix : suffixs) {
// Path file = Paths.get(dir, execute + suffix);
// if (Files.exists(file)) {
// return file.toString();
// }
// }
// }
// return null;
// }
}
50 changes: 50 additions & 0 deletions Codings/CRC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
----------------
CRC16
----------------
import io.netty.buffer.ByteBuf;

public class CRC16 {

private static final int[] LOOKUP_TABLE = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294,
0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420,
0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF,
0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED,
0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33,
0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5,
0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97,
0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2,
0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E,
0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA,
0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615,
0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827,
0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75,
0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B,
0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 };

private CRC16() {
}

public static int crc16(byte[] bytes) {
int crc = 0x0000;

for (byte b : bytes) {
crc = (crc << 8) ^ LOOKUP_TABLE[((crc >>> 8) ^ (b & 0xFF)) & 0xFF];
}
return crc & 0xFFFF;
}

public static int crc16(ByteBuf bytes) {
int crc = 0x0000;

for (int i = 0; i < bytes.readableBytes(); i++) {
crc = (crc << 8) ^ LOOKUP_TABLE[((crc >>> 8) ^ (bytes.readByte() & 0xFF)) & 0xFF];
}

return crc & 0xFFFF;
}
}
File renamed without changes.
4 changes: 4 additions & 0 deletions Freemarker/freemarker-模板语言-指令.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
# 属性
single_line
* bool值,如果该值为 true,则会连换行都一起移除

<#compress>
...
</#compress>

------------
escape |
Expand Down
8 changes: 8 additions & 0 deletions Go/go-vscode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
----------------
vscode 开发环境
----------------
# 编辑器字体(settings.json)
"editor.fontFamily":"Courier New",
"editor.fontWeight": "bold",
"editor.fontSize": 16,

2 changes: 2 additions & 0 deletions Go/lib/os/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type
* 错误输出如果这两个Stdout和Stderr为空的话,则command运行时将响应的文件描述符连接到os.DevNull

ExtraFiles []*os.File
* 指定由新进程继承的其他 open files
* windows 上不支持

SysProcAttr *syscall.SysProcAttr
* 系统进程信息
Expand Down
19 changes: 19 additions & 0 deletions Go/utils/常用方法.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

--------------------------------
获取客户端的真实IP
--------------------------------
// RemoteIP 获取客户端真实的地址
func RemoteIP(ctx *gin.Context) net.IP {
remoteIp := net.ParseIP(ctx.GetHeader("x-forwarded-for"))
if remoteIp == nil {
remoteIp = net.ParseIP(ctx.GetHeader("Proxy-Client-IP"))
if remoteIp == nil {
remoteIp = net.ParseIP(ctx.GetHeader("WL-Proxy-Client-IP"))
if remoteIp == nil {
remoteIp, _ = ctx.RemoteIP()
}
}
}
return remoteIp
}

15 changes: 15 additions & 0 deletions Java/util/zip/CRC32.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-------------
CRC32
-------------
# CRC32 校验器
public class CRC32 implements Checksum


public CRC32()
public void update(int b)
public void update(byte[] b, int off, int len)
public void update(ByteBuffer buffer)
public void reset()
public long getValue()


8 changes: 6 additions & 2 deletions Netty/netty-buffer-ByteBufUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
---------------------------------
# 提供了很多的静态API可以操作buf

byte[] getBytes(ByteBuf buf, int start, int length, boolean copy)
* 读取字节数组不会修改readerIndex
* start 开始角标lengt 读取数量
* copy 默认true返回新的数组如果false会尝过通过反射返回同一个数组底层共享如果尝试失败仍然会copy数组

String hexDump(ByteBuf buffer)
* 返回buffer的16进制字符串,会根据rindex去读取
* 返回buffer的16进制字符串,会根据rindex去读取不会修改ReaderIndex

String hexDump(byte[] array)
* 返回 byte[] 的16进制字符串

byte[] decodeHexDump(CharSequence hexDump)
* 把16进制字符串转换为字节数组



13 changes: 13 additions & 0 deletions Quarkus/cdi/cdi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---------
CDI
---------
# Contexts and Dependency Injection for Java 2.0 (JSR 365规范)

# 文档
https://quarkus.io/guides/cdi
https://quarkus.io/guides/cdi-reference

https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html
https://docs.jboss.org/weld/reference/latest/en-US/html/


7 changes: 7 additions & 0 deletions Quarkus/quarkus-GraalVM.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
----------------
GraalVM
----------------
# 地址
https://www.graalvm.org/
https://github.com/oracle/graal

Loading

0 comments on commit b633d33

Please sign in to comment.