新增:minio分片上传实现;各服务数据库链接池配置优化
This commit is contained in:
@@ -2,9 +2,9 @@ package com.sdm.data.controller;
|
||||
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.data.*;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.data.model.req.RenameFileReq;
|
||||
import com.sdm.common.entity.req.system.LaunchApproveReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.common.feign.inter.data.IDataFeignClient;
|
||||
import com.sdm.data.model.entity.FileMetadataInfo;
|
||||
@@ -383,5 +383,18 @@ public class DataFileController implements IDataFeignClient {
|
||||
return IDataFileService.queryFileMetadataInfo(uuid, uuidOwnType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分片上传文件到minio
|
||||
*
|
||||
* @param req
|
||||
* @return SdmResponse
|
||||
*/
|
||||
@PostMapping("/chunkUploadToMinio")
|
||||
@Operation(summary = "文件分片上传到minio")
|
||||
public SdmResponse<ChunkUploadMinioFileResp> chunkUploadToMinio(ChunkUploadMinioFileReq req) {
|
||||
return IDataFileService.chunkUploadToMinio(req);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -2,11 +2,11 @@ package com.sdm.data.service;
|
||||
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.data.*;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.data.model.entity.FileMetadataInfo;
|
||||
import com.sdm.data.model.req.RenameFileReq;
|
||||
import com.sdm.common.entity.req.system.LaunchApproveReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.data.model.entity.FileMetadataInfo;
|
||||
import com.sdm.data.model.req.*;
|
||||
import com.sdm.data.model.resp.KKFileViewURLFromMinioResp;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@@ -315,4 +315,6 @@ public interface IDataFileService {
|
||||
|
||||
SdmResponse<FileMetadataInfoResp> queryFileMetadataInfo(String uuid, String uuidOwnType);
|
||||
|
||||
SdmResponse<ChunkUploadMinioFileResp> chunkUploadToMinio(ChunkUploadMinioFileReq req);
|
||||
|
||||
}
|
||||
@@ -130,4 +130,8 @@ public interface IMinioService {
|
||||
String getMinioPresignedUrl(String objectKey);
|
||||
String getMinioPresignedUrl(String objectKey, String bucketName);
|
||||
|
||||
Boolean chunkUpload(String bucketName, MultipartFile file, String fileName);
|
||||
|
||||
Boolean merge(String tempBucketName,String tempFilePath,String mergeBucketName,String fileName);
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import com.github.pagehelper.PageInfo;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.common.ThreadLocalContext;
|
||||
import com.sdm.common.entity.constants.NumberConstants;
|
||||
import com.sdm.common.entity.constants.PermConstants;
|
||||
import com.sdm.common.entity.enums.*;
|
||||
import com.sdm.common.entity.req.data.*;
|
||||
import com.sdm.common.entity.req.project.SpdmNodeListReq;
|
||||
@@ -15,6 +16,7 @@ import com.sdm.common.entity.req.system.LaunchApproveReq;
|
||||
import com.sdm.common.entity.req.system.UserListReq;
|
||||
import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.common.entity.resp.project.SimulationNodeResp;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
@@ -51,6 +53,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@@ -86,6 +89,13 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
@Value("${fileSystem.minio}")
|
||||
private String type;
|
||||
|
||||
@Value("${fileSystem.chunkBucket:spdm}")
|
||||
private String chunkBucket;
|
||||
|
||||
// 路径待确定 待配置及初始化
|
||||
@Value("${fileSystem.chunkBasePath:/chunkBase}")
|
||||
private String chunkBasePath;
|
||||
|
||||
@Autowired
|
||||
private IFileMetadataInfoService fileMetadataInfoService;
|
||||
|
||||
@@ -201,6 +211,59 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
return SdmResponse.success(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse<ChunkUploadMinioFileResp> chunkUploadToMinio(ChunkUploadMinioFileReq req) {
|
||||
ChunkUploadMinioFileResp resp = new ChunkUploadMinioFileResp();
|
||||
// 基础路径配置
|
||||
// Long tenantId = ThreadLocalContext.getTenantId();
|
||||
Long tenantId = 123456l;
|
||||
Long userId = 9999l;
|
||||
// Long userId= ThreadLocalContext.getUserId();
|
||||
// -2. 参数校验
|
||||
try {
|
||||
validateReq(req,tenantId,userId);
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("validateReq error:{}", e.getMessage());
|
||||
return buildFailedResponse(resp,e.getMessage(),"",chunkBucket);
|
||||
}
|
||||
// -1.确定文件夹
|
||||
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||
// 合并目录
|
||||
String filePath = org.apache.commons.lang3.StringUtils.isNotBlank(req.getFileDirPath())?
|
||||
req.getFileDirPath():chunkBasePath + "/" + tenantId + "/" + userId +"/" + timestamp + "/";
|
||||
// 0. 一个文件直接传
|
||||
if(Objects.equals(req.getChunkTotal(),NumberConstants.ONE)&&
|
||||
Objects.equals(req.getChunk(),NumberConstants.ONE)){
|
||||
String finalFileName = filePath + req.getSourceFileName();
|
||||
Boolean b = minioService.chunkUpload(chunkBucket, req.getFile(), finalFileName);
|
||||
if(!b){
|
||||
return buildFailedResponse(resp,"单一文件上传失败",filePath,chunkBucket);
|
||||
}
|
||||
return buildSuccessResponse(resp,finalFileName,filePath,chunkBucket);
|
||||
}
|
||||
|
||||
String tempDirPath = filePath +"temp/";
|
||||
// 1. 保存当前分片到临时目录 1 2 3 4 ....temp
|
||||
String chunkFileName =tempDirPath+req.getChunk()+ PermConstants.CHUNK_TEMPFILE_SUFFIX;
|
||||
// 片文件上传到minio
|
||||
Boolean b = minioService.chunkUpload(chunkBucket, req.getFile(), chunkFileName);
|
||||
if(!b){
|
||||
return buildFailedResponse(resp,"chunkUpload第"+req.getChunk()+"次失败",filePath,chunkBucket);
|
||||
}
|
||||
// 2. 判断分片是否已全部上传完毕
|
||||
if (req.getChunk() < req.getChunkTotal()) {
|
||||
return buildSuccessResponse(resp,"",filePath,chunkBucket);
|
||||
}
|
||||
// 3. 全部分片已经上传 => 自动合并
|
||||
String finalFileName = filePath + req.getSourceFileName();
|
||||
Boolean merge = minioService.merge(chunkBucket, tempDirPath, chunkBucket, finalFileName);
|
||||
if(!merge){
|
||||
return buildFailedResponse(resp,req.getSourceFileName()+"合并分片失败",filePath,chunkBucket);
|
||||
}
|
||||
// 4. 合并完成后删除临时目录 todo
|
||||
return buildSuccessResponse(resp,finalFileName,filePath,chunkBucket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验审批回调请求参数的合法性
|
||||
* @param req 审批回调请求对象
|
||||
@@ -1934,4 +1997,44 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验
|
||||
*/
|
||||
private void validateReq(ChunkUploadMinioFileReq req, Long tenantId, Long userId) {
|
||||
// 基础参数校验
|
||||
Assert.notNull(tenantId, "租户ID不能为空");
|
||||
Assert.notNull(userId, "用户ID不能为空");
|
||||
Assert.hasText(req.getSourceFileName(), "原始文件名称不能为空");
|
||||
Assert.notNull(req.getChunk(), "分片编号不能为空");
|
||||
Assert.notNull(req.getChunkTotal(), "分片总数不能为空");
|
||||
Assert.notNull(req.getFile(), "分片文件不能为空");
|
||||
Assert.isTrue(!req.getFile().isEmpty(), "分片文件不能为空");
|
||||
// 业务逻辑校验
|
||||
Assert.isTrue(req.getChunk() >= 1 && req.getChunk() <= req.getChunkTotal(),
|
||||
"分片编号非法:当前" + req.getChunk() + ",总分片" + req.getChunkTotal());
|
||||
Assert.isTrue(req.getChunkTotal() >= 1, "分片总数必须大于等于1");
|
||||
if(req.getChunk() > NumberConstants.ONE) {
|
||||
Assert.hasText(req.getFileDirPath(), "分片父级目录不允许为空");
|
||||
}
|
||||
}
|
||||
|
||||
// 包含业务数据的响应体
|
||||
private SdmResponse<ChunkUploadMinioFileResp> buildSuccessResponse(ChunkUploadMinioFileResp resp, String finalFileName, String fileDirPath,String chunkBucket) {
|
||||
resp.setBucketName(chunkBucket);
|
||||
resp.setFilePath(finalFileName);
|
||||
resp.setFileDirPath(fileDirPath);
|
||||
// 成功时,错误信息通常为空
|
||||
resp.setErrMsg("");
|
||||
return SdmResponse.success(resp);
|
||||
}
|
||||
|
||||
// 构建一个失败的响应对象
|
||||
private SdmResponse<ChunkUploadMinioFileResp> buildFailedResponse(ChunkUploadMinioFileResp resp, String errMsg, String fileDirPath,String chunkBucket) {
|
||||
resp.setBucketName(chunkBucket);
|
||||
resp.setFileDirPath(fileDirPath);
|
||||
// 如果 errMsg 为 null,设置为空字符串 ""
|
||||
resp.setErrMsg(errMsg != null ? errMsg : "");
|
||||
return SdmResponse.failed(resp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,20 +2,16 @@ package com.sdm.data.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sdm.common.common.ResultCode;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.common.SdmIterator;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.common.ThreadLocalContext;
|
||||
import com.sdm.common.entity.constants.PermConstants;
|
||||
import com.sdm.common.entity.data.*;
|
||||
import com.sdm.common.entity.enums.UserRole;
|
||||
import com.sdm.common.entity.pojo.system.SysCompany;
|
||||
import com.sdm.common.entity.pojo.system.SysUserInfo;
|
||||
import com.sdm.common.entity.req.data.CreateDirReq;
|
||||
import com.sdm.common.entity.req.data.DelDirReq;
|
||||
import com.sdm.common.entity.req.data.QueryDirReq;
|
||||
import com.sdm.common.entity.req.data.UploadFilesReq;
|
||||
import com.sdm.common.entity.req.data.*;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.data.model.req.RenameFileReq;
|
||||
import com.sdm.common.service.CommonService;
|
||||
import com.sdm.common.utils.*;
|
||||
import com.sdm.data.dao.DataMapper;
|
||||
@@ -1283,6 +1279,12 @@ public class SystemFileIDataFileServiceImpl implements IDataFileService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse chunkUploadToMinio(ChunkUploadMinioFileReq req) {
|
||||
// 系统盘分片存储暂时不支持
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadFile(DownloadFileReq req, HttpServletResponse response) {
|
||||
if (StringUtils.isNotBlank(req.getPath()) && req.getPath().contains("..")) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.sdm.data.service.minio;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import com.sdm.data.config.MinioConfig;
|
||||
import com.sdm.data.service.IMinioService;
|
||||
import io.minio.*;
|
||||
@@ -21,7 +23,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -423,4 +427,169 @@ public class MinioService implements IMinioService {
|
||||
}
|
||||
return presignedUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* description: 分片碎文件上传
|
||||
*
|
||||
* @param bucketName 桶名称
|
||||
* @param file 文件
|
||||
* @param fileName /xx/xx/文件名,数字类型,1 2 3 ... .temp
|
||||
* @author bo
|
||||
* @date 2023/5/21 13:06
|
||||
*/
|
||||
@Override
|
||||
public Boolean chunkUpload(String bucketName, MultipartFile file, String fileName) {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = file.getInputStream();
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(fileName)
|
||||
.stream(inputStream, file.getSize(), -1)
|
||||
.build());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("chunkUpload error:{}",e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("chunkUpload finally error:{}",e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分片上传合并
|
||||
/**
|
||||
* 讲快文件合并到新桶 块文件必须满足 名字是 0 1 2 3 5....
|
||||
*
|
||||
* @param tempBucketName 存块文件的桶
|
||||
* @param tempFilePath 存块文件的文件夹路径
|
||||
* @param mergeBucketName 存新文件的桶
|
||||
* @param fileName 存到新桶中的文件名称
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public Boolean merge(String tempBucketName,String tempFilePath,String mergeBucketName,String fileName) {
|
||||
try {
|
||||
List<ComposeSource> sourceObjectList = new ArrayList<ComposeSource>();
|
||||
List<Object> folderList = getFolderList(tempBucketName,tempFilePath);
|
||||
List<String> fileNames = new ArrayList<>();
|
||||
if (!folderList.isEmpty()) {
|
||||
for (Object value : folderList) {
|
||||
Map o = (Map) value;
|
||||
String name = (String) o.get("fileName");
|
||||
fileNames.add(name);
|
||||
}
|
||||
}
|
||||
if (!fileNames.isEmpty()) {
|
||||
fileNames.sort((fileName1, fileName2) -> {
|
||||
int num1 = getFileNumber(fileName1);
|
||||
int num2 = getFileNumber(fileName2);
|
||||
return Integer.compare(num1, num2);
|
||||
});
|
||||
for (String name : fileNames) {
|
||||
sourceObjectList.add(ComposeSource.builder().bucket(tempBucketName).object(name).build());
|
||||
}
|
||||
}
|
||||
minioClient.composeObject(
|
||||
ComposeObjectArgs.builder()
|
||||
.bucket(mergeBucketName)
|
||||
.object(fileName)
|
||||
.sources(sourceObjectList)
|
||||
.build());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("merge error:{},fileName:{}",e.getMessage(),fileName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Object> getFolderList(String bucketName, String tempFilePath) {
|
||||
List<Object> items = new ArrayList<>();
|
||||
if(org.apache.commons.lang3.StringUtils.isBlank(tempFilePath)){
|
||||
CoreLogger.warn("getFolderList tempFilePath null");
|
||||
return items;
|
||||
}
|
||||
try {
|
||||
// 1. 规范化 prefix:去除开头的 /,目录路径末尾补 /(根目录除外)
|
||||
String prefix = tempFilePath;
|
||||
// 去除开头的 /
|
||||
prefix = prefix.replaceAll("^/", "");
|
||||
// 如果不是空字符串(根目录),且末尾没有 /,则补 /
|
||||
if (!prefix.isEmpty() && !prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
// 2. 调用 listObjects,使用规范化后的 prefix
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.prefix(prefix) // 关键:使用规范化后的前缀
|
||||
.recursive(false) // 只查当前前缀的直接子对象(即“当前目录”下的文件)
|
||||
.build()
|
||||
);
|
||||
Iterator<Result<Item>> iterator = results.iterator();
|
||||
items = new ArrayList<>();
|
||||
String format = "{'fileName':'%s','fileSize':'%s'}";
|
||||
while (iterator.hasNext()) {
|
||||
Item item = iterator.next().get();
|
||||
// 注意:item.objectName() 是完整的对象键(比如 a/b/c/1.txt),如果需要相对路径,可做截取
|
||||
items.add(JSON.parse((String.format(format, item.objectName(),
|
||||
formatFileSize(item.size())))));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("getFolderList error:{},tempFilePath:{}",e.getMessage(),tempFilePath);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* description: 格式化文件大小
|
||||
*
|
||||
* @param fileS 文件的字节长度
|
||||
* @author bo
|
||||
* @date 2023/5/21 11:40
|
||||
*/
|
||||
private static String formatFileSize(long fileS) {
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
String fileSizeString = "";
|
||||
String wrongSize = "0B";
|
||||
if (fileS == 0) {
|
||||
return wrongSize;
|
||||
}
|
||||
if (fileS < 1024) {
|
||||
fileSizeString = df.format((double) fileS) + " B";
|
||||
} else if (fileS < 1048576) {
|
||||
fileSizeString = df.format((double) fileS / 1024) + " KB";
|
||||
} else if (fileS < 1073741824) {
|
||||
fileSizeString = df.format((double) fileS / 1048576) + " MB";
|
||||
} else {
|
||||
fileSizeString = df.format((double) fileS / 1073741824) + " GB";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从固定格式的文件名中截取数字。
|
||||
* 格式必须是:.../数字.temp
|
||||
*/
|
||||
private static int getFileNumber(String fileName) {
|
||||
try {
|
||||
int lastSlashIndex = fileName.lastIndexOf('/');
|
||||
int dotIndex = fileName.lastIndexOf('.');
|
||||
// 截取数字部分的字符串
|
||||
String numberStr = fileName.substring(lastSlashIndex + 1, dotIndex);
|
||||
// 转换为整数
|
||||
return Integer.parseInt(numberStr);
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("getFileNumber error:{},fileName:{}",e.getMessage(),fileName);
|
||||
throw new RuntimeException("临时文件名格式非数字.temp类型");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -10,11 +10,16 @@ spring:
|
||||
jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
maximum-pool-size: 450 # 连接池最大连接数(关键!)
|
||||
minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁)
|
||||
idle-timeout: 300000 # 空闲连接超时时间(5分钟)
|
||||
max-lifetime: 600000 # 连接最大存活时间(10分钟)
|
||||
connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞)
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
maximum-pool-size: 20
|
||||
# 连接池在空闲时保持的最小连接数。
|
||||
minimum-idle: 5
|
||||
# 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。
|
||||
idle-timeout: 60000 # 1 min
|
||||
# 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。
|
||||
max-lifetime: 1800000 # 30 min(Hikari 默认)
|
||||
# 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。
|
||||
connection-timeout: 30000 # 30s
|
||||
master:
|
||||
username: root
|
||||
password: mysql
|
||||
|
||||
@@ -10,11 +10,16 @@ spring:
|
||||
jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
maximum-pool-size: 450 # 连接池最大连接数(关键!)
|
||||
minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁)
|
||||
idle-timeout: 300000 # 空闲连接超时时间(5分钟)
|
||||
max-lifetime: 600000 # 连接最大存活时间(10分钟)
|
||||
connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞)
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
maximum-pool-size: 20
|
||||
# 连接池在空闲时保持的最小连接数。
|
||||
minimum-idle: 5
|
||||
# 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。
|
||||
idle-timeout: 60000 # 1 min
|
||||
# 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。
|
||||
max-lifetime: 1800000 # 30 min(Hikari 默认)
|
||||
# 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。
|
||||
connection-timeout: 30000 # 30s
|
||||
master:
|
||||
username: root
|
||||
password: mysql
|
||||
|
||||
@@ -6,11 +6,16 @@ spring:
|
||||
name: data
|
||||
datasource:
|
||||
hikari:
|
||||
maximum-pool-size: 450 # 连接池最大连接数(关键!)
|
||||
minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁)
|
||||
idle-timeout: 300000 # 空闲连接超时时间(5分钟)
|
||||
max-lifetime: 600000 # 连接最大存活时间(10分钟)
|
||||
connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞)
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
maximum-pool-size: 20
|
||||
# 连接池在空闲时保持的最小连接数。
|
||||
minimum-idle: 5
|
||||
# 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。
|
||||
idle-timeout: 60000 # 1 min
|
||||
# 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。
|
||||
max-lifetime: 1800000 # 30 min(Hikari 默认)
|
||||
# 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。
|
||||
connection-timeout: 30000 # 30s
|
||||
master:
|
||||
username: root
|
||||
password: ENC(+QKYnI6gAYu1SbLaZQTkZA==)
|
||||
|
||||
@@ -6,11 +6,16 @@ spring:
|
||||
name: data
|
||||
datasource:
|
||||
hikari:
|
||||
maximum-pool-size: 450 # 连接池最大连接数(关键!)
|
||||
minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁)
|
||||
idle-timeout: 300000 # 空闲连接超时时间(5分钟)
|
||||
max-lifetime: 600000 # 连接最大存活时间(10分钟)
|
||||
connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞)
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
maximum-pool-size: 20
|
||||
# 连接池在空闲时保持的最小连接数。
|
||||
minimum-idle: 5
|
||||
# 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。
|
||||
idle-timeout: 60000 # 1 min
|
||||
# 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。
|
||||
max-lifetime: 1800000 # 30 min(Hikari 默认)
|
||||
# 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。
|
||||
connection-timeout: 30000 # 30s
|
||||
master:
|
||||
username: root
|
||||
password: ENC(+QKYnI6gAYu1SbLaZQTkZA==)
|
||||
|
||||
Reference in New Issue
Block a user