@@ -43,7 +43,7 @@ public class SwaggerConfig { | |||
.tags(new springfox.documentation.service.Tag("车辆管理", "车辆信息相关接口")) | |||
.tags(new springfox.documentation.service.Tag("称重记录", "称重记录相关接口")); | |||
} | |||
/** | |||
* API信息配置 | |||
*/ | |||
@@ -55,7 +55,7 @@ public class SwaggerConfig { | |||
.contact(new Contact("开发团队", "http://www.example.com", "dev@example.com")) | |||
.build(); | |||
} | |||
/** | |||
* 获取全局请求参数 | |||
* 注意:在Swagger UI中这些参数设置为非必需,以便能够正常访问Swagger界面 | |||
@@ -63,7 +63,7 @@ public class SwaggerConfig { | |||
*/ | |||
private List<Parameter> getGlobalParameters() { | |||
List<Parameter> parameters = new ArrayList<>(); | |||
// AK (Access Key) - 在Swagger中设为非必需,便于测试 | |||
Parameter akParam = new ParameterBuilder() | |||
.name("ak") | |||
@@ -73,7 +73,7 @@ public class SwaggerConfig { | |||
.required(false) // 改为false,让Swagger UI可以正常访问 | |||
.build(); | |||
parameters.add(akParam); | |||
// Timestamp - 在Swagger中设为非必需,便于测试 | |||
Parameter timestampParam = new ParameterBuilder() | |||
.name("timestamp") | |||
@@ -83,7 +83,7 @@ public class SwaggerConfig { | |||
.required(false) // 改为false,让Swagger UI可以正常访问 | |||
.build(); | |||
parameters.add(timestampParam); | |||
// Signature - 在Swagger中设为非必需,便于测试 | |||
Parameter signatureParam = new ParameterBuilder() | |||
.name("signature") | |||
@@ -93,7 +93,7 @@ public class SwaggerConfig { | |||
.required(false) // 改为false,让Swagger UI可以正常访问 | |||
.build(); | |||
parameters.add(signatureParam); | |||
return parameters; | |||
} | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package com.example.webapi.entity; | |||
import lombok.Data; | |||
import javax.persistence.*; | |||
import java.util.Date; | |||
@Data | |||
@Entity | |||
@Table(name = "TB_ONCEWEIGHING") | |||
public class OnceWeighing { | |||
@Id | |||
@Column(name = "NODEID", length = 22, nullable = false) | |||
private String nodeId; | |||
@Column(name = "LISTID", length = 18) | |||
private String listId; | |||
@Column(name = "WEIGHT") | |||
private Double weight; | |||
@Column(name = "SPEED") | |||
private Double speed; | |||
@Column(name = "NODETIME") | |||
private Date nodeTime; | |||
@Column(name = "OPERATORID", length = 8) | |||
private String operatorId; | |||
@Column(name = "VEHICLETYPE", length = 10) | |||
private String vehicleType; | |||
@Column(name = "VEHICLEID", length = 10) | |||
private String vehicleId; | |||
@Column(name = "MANAGEFLAG") | |||
private Boolean manageFlag; | |||
@Column(name = "SNAPPICTIME", length = 14) | |||
private String snapPicTime; | |||
@Column(name = "UPLOADFLAG") | |||
private Boolean uploadFlag; | |||
@Column(name = "USELESSFLAG") | |||
private Boolean uselessFlag; | |||
@Column(name = "DEMO", length = 50) | |||
private String demo; | |||
@Column(name = "SCALEID", length = 10) | |||
private String scaleId; | |||
@Column(name = "GROSSORTARE", length = 1) | |||
private String grossOrTare; | |||
@Column(name = "BEFOREANDAFTERSLANTCARRY") | |||
private Double beforeAndAfterSlantCarry; | |||
@Column(name = "LEFTANDRIGHTLANTCARRY") | |||
private Double leftAndRightLantCarry; | |||
} |
@@ -0,0 +1,62 @@ | |||
package com.example.webapi.entity.postgresql; | |||
import lombok.Data; | |||
import javax.persistence.*; | |||
import java.util.Date; | |||
@Data | |||
@Entity | |||
@Table(name = "tb_once_weighing") | |||
public class OnceWeighingPostgreSQL { | |||
@Id | |||
@Column(name = "node_id", length = 22, nullable = false) | |||
private String nodeId; | |||
@Column(name = "list_id", length = 18) | |||
private String listId; | |||
@Column(name = "weight") | |||
private Double weight; | |||
@Column(name = "speed") | |||
private Double speed; | |||
@Column(name = "node_time") | |||
private Date nodeTime; | |||
@Column(name = "operator_id", length = 8) | |||
private String operatorId; | |||
@Column(name = "vehicle_type", length = 10) | |||
private String vehicleType; | |||
@Column(name = "vehicle_id", length = 10) | |||
private String vehicleId; | |||
@Column(name = "manage_flag") | |||
private Boolean manageFlag; | |||
@Column(name = "snap_pic_time", length = 14) | |||
private String snapPicTime; | |||
@Column(name = "upload_flag") | |||
private Boolean uploadFlag; | |||
@Column(name = "useless_flag") | |||
private Boolean uselessFlag; | |||
@Column(name = "demo", length = 50) | |||
private String demo; | |||
@Column(name = "scale_id", length = 10) | |||
private String scaleId; | |||
@Column(name = "gross_or_tare", length = 1) | |||
private String grossOrTare; | |||
@Column(name = "before_and_after_slant_carry") | |||
private Double beforeAndAfterSlantCarry; | |||
@Column(name = "left_and_right_lant_carry") | |||
private Double leftAndRightLantCarry; | |||
} |
@@ -0,0 +1,16 @@ | |||
package com.example.webapi.repository; | |||
import com.example.webapi.entity.OnceWeighing; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; | |||
import org.springframework.data.domain.Page; | |||
import org.springframework.data.domain.Pageable; | |||
import org.springframework.stereotype.Repository; | |||
import java.util.List; | |||
@Repository("onceWeighingRepository") | |||
public interface OnceWeighingRepository extends JpaRepository<OnceWeighing, String>, JpaSpecificationExecutor<OnceWeighing> { | |||
List<OnceWeighing> findByUploadFlag(Boolean uploadFlag); | |||
List<OnceWeighing> findByNodeTimeAfter(java.util.Date nodeTime); | |||
Page<OnceWeighing> findByNodeTimeNotNullOrderByNodeTimeDesc(Pageable pageable); | |||
} |
@@ -0,0 +1,17 @@ | |||
package com.example.webapi.repository.pg; | |||
import com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
import org.springframework.data.jpa.repository.Query; | |||
import org.springframework.data.repository.query.Param; | |||
import org.springframework.stereotype.Repository; | |||
import java.util.List; | |||
@Repository | |||
public interface OnceWeighingPostgreSQLRepository extends JpaRepository<OnceWeighingPostgreSQL, String> { | |||
@Query("SELECT o FROM OnceWeighingPostgreSQL o WHERE o.uploadFlag = :uploadFlag") | |||
List<OnceWeighingPostgreSQL> findByUploadFlag(@Param("uploadFlag") Boolean uploadFlag); | |||
@Query("SELECT MAX(o.nodeTime) FROM OnceWeighingPostgreSQL o WHERE o.nodeTime IS NOT NULL") | |||
java.util.Date findMaxNodeTime(); | |||
} |
@@ -22,6 +22,7 @@ import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import java.util.stream.Collectors; | |||
@Service | |||
public class DataSyncService { | |||
@@ -34,6 +35,13 @@ public class DataSyncService { | |||
@Qualifier("twiceWeighingPostgreSQLRepository") | |||
private TwiceWeighingPostgreSQLRepository twiceWeighingPostgreSQLRepository; | |||
@Autowired | |||
@Qualifier("onceWeighingRepository") | |||
private com.example.webapi.repository.OnceWeighingRepository onceWeighingRepository; | |||
@Autowired | |||
private com.example.webapi.repository.pg.OnceWeighingPostgreSQLRepository onceWeighingPostgreSQLRepository; | |||
/** | |||
* 同步单条数据 | |||
*/ | |||
@@ -349,4 +357,182 @@ public class DataSyncService { | |||
target.setIronNumber(source.getIronNumber()); | |||
target.setDirection(source.getDirection()); | |||
} | |||
/** | |||
* 一次过磅-同步所有未上传的数据 - 分批处理 | |||
*/ | |||
@Transactional(transactionManager = "postgresqlTransactionManager") | |||
public int syncOnceUnuploadedRecords() { | |||
return syncOnceUnuploadedRecords(500); | |||
} | |||
/** | |||
* 一次过磅-同步所有未上传的数据 - 指定批次大小 | |||
*/ | |||
@Transactional(transactionManager = "postgresqlTransactionManager") | |||
public int syncOnceUnuploadedRecords(int batchSize) { | |||
try { | |||
List<com.example.webapi.entity.OnceWeighing> unuploadedRecords = onceWeighingRepository.findByUploadFlag(false); | |||
int totalRecords = unuploadedRecords.size(); | |||
int successCount = 0; | |||
int batchCount = 0; | |||
for (int i = 0; i < totalRecords; i += batchSize) { | |||
int endIndex = Math.min(i + batchSize, totalRecords); | |||
List<com.example.webapi.entity.OnceWeighing> batchRecords = unuploadedRecords.subList(i, endIndex); | |||
batchCount++; | |||
int batchSuccessCount = processOnceBatch(batchRecords); | |||
successCount += batchSuccessCount; | |||
} | |||
return successCount; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return 0; | |||
} | |||
} | |||
/** | |||
* 一次过磅-全量同步 | |||
*/ | |||
@Transactional(transactionManager = "postgresqlTransactionManager") | |||
public int syncOnceAllData() { | |||
return syncOnceAllData(500); | |||
} | |||
@Transactional(transactionManager = "postgresqlTransactionManager") | |||
public int syncOnceAllData(int batchSize) { | |||
try { | |||
List<com.example.webapi.entity.OnceWeighing> allRecords = onceWeighingRepository.findAll(); | |||
// org.springframework.data.domain.PageRequest pageRequest = org.springframework.data.domain.PageRequest.of(0, 500, org.springframework.data.domain.Sort.by(org.springframework.data.domain.Sort.Direction.DESC, "nodeTime")); | |||
// List<com.example.webapi.entity.OnceWeighing> allRecords = onceWeighingRepository.findByNodeTimeNotNullOrderByNodeTimeDesc(pageRequest).getContent(); | |||
int totalRecords = allRecords.size(); | |||
int successCount = 0; | |||
int batchCount = 0; | |||
for (int i = 0; i < totalRecords; i += batchSize) { | |||
int endIndex = Math.min(i + batchSize, totalRecords); | |||
List<com.example.webapi.entity.OnceWeighing> batchRecords = allRecords.subList(i, endIndex); | |||
batchCount++; | |||
int batchSuccessCount = processOnceBatch(batchRecords); | |||
successCount += batchSuccessCount; | |||
} | |||
return successCount; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return 0; | |||
} | |||
} | |||
/** | |||
* 一次过磅-增量同步(基于node_time,数据库层面过滤) | |||
*/ | |||
@Transactional(transactionManager = "postgresqlTransactionManager") | |||
public int syncOnceIncrementalData() { | |||
try { | |||
// 获取PostgreSQL中最大的node_time(数据库层面) | |||
java.util.Date maxNodeTime = onceWeighingPostgreSQLRepository.findMaxNodeTime(); | |||
if (maxNodeTime == null) { | |||
return syncOnceAllData(); | |||
} | |||
// 数据库层面过滤增量数据 | |||
List<com.example.webapi.entity.OnceWeighing> incrementalRecords = onceWeighingRepository.findByNodeTimeAfter(maxNodeTime); | |||
int successCount = 0; | |||
for (com.example.webapi.entity.OnceWeighing source : incrementalRecords) { | |||
try { | |||
com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL target = convertOnceToPostgreSQL(source); | |||
java.util.Optional<com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL> existingRecord = onceWeighingPostgreSQLRepository.findById(source.getNodeId()); | |||
if (existingRecord.isPresent()) { | |||
com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL existing = existingRecord.get(); | |||
updateOncePostgreSQLRecord(existing, source); | |||
onceWeighingPostgreSQLRepository.saveAndFlush(existing); | |||
} else { | |||
onceWeighingPostgreSQLRepository.saveAndFlush(target); | |||
} | |||
successCount++; | |||
} catch (Exception e) { | |||
System.err.println("同步记录失败,NODEID: " + source.getNodeId() + ", 错误: " + e.getMessage()); | |||
} | |||
} | |||
return successCount; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return 0; | |||
} | |||
} | |||
/** | |||
* 一次过磅-批量处理 | |||
*/ | |||
private int processOnceBatch(List<com.example.webapi.entity.OnceWeighing> batchRecords) { | |||
int successCount = 0; | |||
List<com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL> entitiesToSave = new java.util.ArrayList<>(); | |||
for (com.example.webapi.entity.OnceWeighing source : batchRecords) { | |||
try { | |||
com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL target = convertOnceToPostgreSQL(source); | |||
entitiesToSave.add(target); | |||
successCount++; | |||
} catch (Exception e) { | |||
System.err.println("处理记录失败,NODEID: " + source.getNodeId() + ", 错误: " + e.getMessage()); | |||
} | |||
} | |||
if (!entitiesToSave.isEmpty()) { | |||
try { | |||
onceWeighingPostgreSQLRepository.saveAllAndFlush(entitiesToSave); | |||
} catch (Exception e) { | |||
for (com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL entity : entitiesToSave) { | |||
try { | |||
onceWeighingPostgreSQLRepository.save(entity); | |||
} catch (Exception ex) { | |||
System.err.println("单条插入失败,NODEID: " + entity.getNodeId() + ", 错误: " + ex.getMessage()); | |||
} | |||
} | |||
} | |||
} | |||
return successCount; | |||
} | |||
/** | |||
* 一次过磅-SQLServer实体转PostgreSQL实体 | |||
*/ | |||
private com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL convertOnceToPostgreSQL(com.example.webapi.entity.OnceWeighing source) { | |||
com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL target = new com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL(); | |||
target.setNodeId(source.getNodeId()); | |||
target.setListId(source.getListId()); | |||
target.setWeight(source.getWeight()); | |||
target.setSpeed(source.getSpeed()); | |||
target.setNodeTime(source.getNodeTime()); | |||
target.setOperatorId(source.getOperatorId()); | |||
target.setVehicleType(source.getVehicleType()); | |||
target.setVehicleId(source.getVehicleId()); | |||
target.setManageFlag(source.getManageFlag()); | |||
target.setSnapPicTime(source.getSnapPicTime()); | |||
target.setUploadFlag(source.getUploadFlag()); | |||
target.setUselessFlag(source.getUselessFlag()); | |||
target.setDemo(source.getDemo()); | |||
target.setScaleId(source.getScaleId()); | |||
target.setGrossOrTare(source.getGrossOrTare()); | |||
target.setBeforeAndAfterSlantCarry(source.getBeforeAndAfterSlantCarry()); | |||
target.setLeftAndRightLantCarry(source.getLeftAndRightLantCarry()); | |||
return target; | |||
} | |||
/** | |||
* 一次过磅-更新PostgreSQL记录 | |||
*/ | |||
private void updateOncePostgreSQLRecord(com.example.webapi.entity.postgresql.OnceWeighingPostgreSQL target, com.example.webapi.entity.OnceWeighing source) { | |||
target.setListId(source.getListId()); | |||
target.setWeight(source.getWeight()); | |||
target.setSpeed(source.getSpeed()); | |||
target.setNodeTime(source.getNodeTime()); | |||
target.setOperatorId(source.getOperatorId()); | |||
target.setVehicleType(source.getVehicleType()); | |||
target.setVehicleId(source.getVehicleId()); | |||
target.setManageFlag(source.getManageFlag()); | |||
target.setSnapPicTime(source.getSnapPicTime()); | |||
target.setUploadFlag(source.getUploadFlag()); | |||
target.setUselessFlag(source.getUselessFlag()); | |||
target.setDemo(source.getDemo()); | |||
target.setScaleId(source.getScaleId()); | |||
target.setGrossOrTare(source.getGrossOrTare()); | |||
target.setBeforeAndAfterSlantCarry(source.getBeforeAndAfterSlantCarry()); | |||
target.setLeftAndRightLantCarry(source.getLeftAndRightLantCarry()); | |||
} | |||
} |
@@ -34,25 +34,54 @@ public class ScheduledSyncService implements CommandLineRunner { | |||
} | |||
} | |||
// /** | |||
// * 每天凌晨2点执行全量同步检查 | |||
// */ | |||
// @Scheduled(cron = "0 0 2 * * ?") | |||
// public void dailyFullSync() { | |||
// try { | |||
// logger.info("开始每日全量同步检查..."); | |||
// int count = dataSyncService.syncIncrementalData(); | |||
// logger.info("每日全量同步检查完成,成功同步 {} 条记录", count); | |||
// } catch (Exception e) { | |||
// logger.error("每日全量同步检查过程中发生错误: {}", e.getMessage(), e); | |||
// } | |||
// } | |||
/** | |||
* 每天凌晨2点执行全量同步检查 | |||
* 每5分钟执行一次一次过磅增量同步 | |||
*/ | |||
@Scheduled(cron = "0 0 2 * * ?") | |||
public void dailyFullSync() { | |||
@Scheduled(fixedRate = 300000) // 5分钟 = 300000毫秒 | |||
public void syncOnceIncrementalData() { | |||
try { | |||
logger.info("开始每日全量同步检查..."); | |||
int count = dataSyncService.syncIncrementalData(); | |||
logger.info("每日全量同步检查完成,成功同步 {} 条记录", count); | |||
logger.info("开始定时一次过磅增量同步数据..."); | |||
int count = dataSyncService.syncOnceIncrementalData(); | |||
logger.info("定时一次过磅增量同步完成,成功同步 {} 条记录", count); | |||
} catch (Exception e) { | |||
logger.error("每日全量同步检查过程中发生错误: {}", e.getMessage(), e); | |||
logger.error("定时一次过磅增量同步过程中发生错误: {}", e.getMessage(), e); | |||
} | |||
} | |||
// /** | |||
// * 每天凌晨2点执行一次过磅全量同步检查 | |||
// */ | |||
// @Scheduled(cron = "0 5 2 * * ?") // 比二次过磅晚5分钟 | |||
// public void dailyOnceFullSync() { | |||
// try { | |||
// logger.info("开始每日一次过磅全量同步检查..."); | |||
// int count = dataSyncService.syncOnceAllData(); | |||
// logger.info("每日一次过磅全量同步检查完成,成功同步 {} 条记录", count); | |||
// } catch (Exception e) { | |||
// logger.error("每日一次过磅全量同步检查过程中发生错误: {}", e.getMessage(), e); | |||
// } | |||
// } | |||
@Override | |||
public void run(String... args) throws Exception { | |||
System.out.println("项目启动后执行增量同步------------------"); | |||
try { | |||
syncIncrementalData(); | |||
// syncIncrementalData(); | |||
syncOnceIncrementalData(); | |||
} catch (Exception e) { | |||
logger.error("启动时增量同步失败: {}", e.getMessage(), e); | |||
} | |||
@@ -0,0 +1,76 @@ | |||
server: | |||
port: 8806 | |||
servlet: | |||
context-path: /fuquanapi | |||
spring: | |||
application: | |||
name: fuquanapi | |||
main: | |||
allow-bean-definition-overriding: true | |||
datasource: | |||
# SQL Server数据源配置 | |||
sqlserver: | |||
# 西宁火车煤 - 备用配置 | |||
url: jdbc:sqlserver://192.168.35.216:1433;SelectMethod=cursor;rewriteBatchedStatements=true;DatabaseName=WY_DATAMANAGE;encrypt=false;trustServerCertificate=true | |||
username: sa | |||
password: sa | |||
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver | |||
# url: jdbc:sqlserver://112.33.47.173:6789;SelectMethod=cursor;rewriteBatchedStatements=true;DatabaseName=WY_DATAMANAGE20250731;encrypt=false;trustServerCertificate=true | |||
# username: admin | |||
# password: admin@Erp2021 | |||
# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver | |||
# 连接池配置 | |||
hikari: | |||
maximum-pool-size: 10 | |||
minimum-idle: 5 | |||
connection-timeout: 30000 | |||
idle-timeout: 600000 | |||
max-lifetime: 1800000 | |||
# PostgreSQL数据源配置 | |||
postgresql: | |||
url: jdbc:postgresql://192.168.35.10:5435/auseft_web | |||
username: postgres | |||
password: Auseft@2025 | |||
driver-class-name: org.postgresql.Driver | |||
# 连接池配置 | |||
hikari: | |||
maximum-pool-size: 10 | |||
minimum-idle: 5 | |||
connection-timeout: 30000 | |||
idle-timeout: 600000 | |||
max-lifetime: 1800000 | |||
jpa: | |||
hibernate: | |||
ddl-auto: none | |||
show-sql: true | |||
properties: | |||
hibernate: | |||
dialect: org.hibernate.dialect.SQLServer2008Dialect | |||
format_sql: true | |||
physical_naming_strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl | |||
use_sql_comments: true | |||
# 禁用默认数据源自动配置 | |||
open-in-view: false | |||
jackson: | |||
date-format: yyyy-MM-dd HH:mm:ss | |||
time-zone: GMT+8 | |||
mvc: | |||
pathmatch: | |||
matching-strategy: ant_path_matcher | |||
# API客户端配置 | |||
api: | |||
client: | |||
ak: 2760cd7c-cc0e-4034-86f3-d58e89f03d80 | |||
sk: e2c0e9c1aaa72a0b1444f879c86a9034bf2f03be31a58b1e5b3b077948da75cf | |||
# 日志配置 | |||
logging: | |||
level: | |||
com.example.webapi: DEBUG | |||
pattern: | |||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" | |||
# Swagger配置 - Swagger2不需要额外配置 |
@@ -12,8 +12,6 @@ APP_CONTEXT_PATH="/fuquanapi" | |||
# JVM配置 | |||
JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseStringDeduplication" | |||
JVM_OPTS="$JVM_OPTS -Dserver.port=$APP_PORT" | |||
JVM_OPTS="$JVM_OPTS -Dserver.servlet.context-path=$APP_CONTEXT_PATH" | |||
# 日志配置 | |||
LOG_DIR="./logs" | |||
@@ -55,6 +53,16 @@ check_jar() { | |||
print_message $GREEN "找到应用JAR文件: $APP_JAR" | |||
} | |||
# 检查配置文件 | |||
check_config() { | |||
if [ -f "./application.yml" ]; then | |||
print_message $GREEN "找到外部配置文件: ./application.yml" | |||
print_message $BLUE "Spring Boot将自动使用外部配置文件" | |||
else | |||
print_message $YELLOW "未找到外部配置文件 ./application.yml,将使用JAR包内的默认配置" | |||
fi | |||
} | |||
# 创建日志目录 | |||
create_log_dir() { | |||
if [ ! -d "$LOG_DIR" ]; then | |||
@@ -81,6 +89,9 @@ check_running() { | |||
# 启动应用 | |||
start_app() { | |||
print_message $BLUE "正在启动 $APP_NAME..." | |||
# 检查配置文件 | |||
check_config | |||
# 启动应用 | |||
nohup java $JVM_OPTS -jar "$APP_JAR" > "$LOG_FILE" 2>&1 & | |||
@@ -236,4 +247,4 @@ main() { | |||
} | |||
# 执行主函数 | |||
main "$@" | |||
main "$@" |