平滑,并避免编码

This commit is contained in:
sladro 2026-02-11 12:59:44 +08:00
parent 7bb910892a
commit c3f44b3c90
5 changed files with 65 additions and 49 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml,json,xml}]
indent_size = 2
[Makefile]
indent_style = tab

31
.gitattributes vendored Normal file
View File

@ -0,0 +1,31 @@
* text=auto
# Enforce UTF-8 text files in repository and normalized LF line endings.
*.java text eol=lf working-tree-encoding=UTF-8
*.kt text eol=lf working-tree-encoding=UTF-8
*.groovy text eol=lf working-tree-encoding=UTF-8
*.xml text eol=lf working-tree-encoding=UTF-8
*.properties text eol=lf working-tree-encoding=UTF-8
*.yml text eol=lf working-tree-encoding=UTF-8
*.yaml text eol=lf working-tree-encoding=UTF-8
*.json text eol=lf working-tree-encoding=UTF-8
*.sql text eol=lf working-tree-encoding=UTF-8
*.sh text eol=lf working-tree-encoding=UTF-8
*.md text eol=lf working-tree-encoding=UTF-8
# Windows scripts keep CRLF for direct execution.
*.bat text eol=crlf working-tree-encoding=UTF-8
*.cmd text eol=crlf working-tree-encoding=UTF-8
*.ps1 text eol=crlf working-tree-encoding=UTF-8
# Binary files must never be normalized.
*.jar binary
*.war binary
*.zip binary
*.gz binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary

View File

@ -11,6 +11,7 @@
<properties>
<qaup.version>1.0.1</qaup.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.resourcesEncoding>UTF-8</project.build.resourcesEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>21</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
@ -292,6 +293,14 @@
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<encoding>${project.build.resourcesEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

View File

@ -33,7 +33,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
@ -85,10 +84,6 @@ public class DataCollectorService {
* - 在多线程调度器下若上游抖动/超时fixedRate 会产生并发重入
* - 这里用 AtomicBoolean 做最小侵入的防重入保护不改变正常情况下的业务逻辑
*/
private final AtomicBoolean aircraftCollectInProgress = new AtomicBoolean(false);
private final AtomicBoolean vehicleCollectInProgress = new AtomicBoolean(false);
private final AtomicBoolean unmannedCollectInProgress = new AtomicBoolean(false);
@Autowired
private DataCollectorDao dataCollectorDao;
@ -539,18 +534,14 @@ public class DataCollectorService {
return 6371000.0 * c;
}
@Scheduled(fixedRateString = "${data.collector.interval}")
// Fixed-delay scheduling prevents overlap without dropping cycles.
@Scheduled(fixedDelayString = "${data.collector.interval}")
public void collectAircraftData() {
if (collectorDisabled) {
return;
}
// 丢弃旧轮次上一轮未完成时跳过避免任务堆积
if (!aircraftCollectInProgress.compareAndSet(false, true)) {
log.warn("航空器采集上一轮尚未完成,跳过本轮以避免堆积(保持实时性)");
return;
}
try {
List<Aircraft> newAircrafts = dataCollectorDao.collectAircraftData(airportAircraftEndpoint, airportBaseUrl);
if (newAircrafts.isEmpty()) {
@ -606,8 +597,6 @@ public class DataCollectorService {
} catch (Exception e) {
log.error("采集航空器数据异常", e);
} finally {
aircraftCollectInProgress.set(false);
}
}
@ -621,19 +610,13 @@ public class DataCollectorService {
* - 数据采集后直接用于碰撞检测等实时计算
* - 不进行数据持久化
*/
@Scheduled(fixedRateString = "${data.collector.interval}")
@Async // 异步执行
@Scheduled(fixedDelayString = "${data.collector.interval}")
public void collectVehicleData() {
if (collectorDisabled) {
return;
}
// 丢弃旧轮次上一轮未完成时跳过避免 fixedRate + @Async 并发堆积
if (!vehicleCollectInProgress.compareAndSet(false, true)) {
log.warn("机场车辆采集上一轮尚未完成,跳过本轮以避免堆积(保持实时性)");
return;
}
try {
List<AirportVehicle> vehicles = dataCollectorDao.collectVehicleData(airportVehicleEndpoint, airportBaseUrl);
if (vehicles.isEmpty()) {
@ -701,8 +684,6 @@ public class DataCollectorService {
} catch (Exception e) {
log.error("采集机场车辆数据异常", e);
} finally {
vehicleCollectInProgress.set(false);
}
}
@ -716,19 +697,13 @@ public class DataCollectorService {
* - 包含missionContext任务信息支持里程和路径点数据
* - 数据仅用于实时处理不存储到数据库
*/
@Scheduled(fixedRateString = "${data.collector.vehicle-manager.http.poll-interval-ms:1000}")
@Async // 异步执行
@Scheduled(fixedDelayString = "${data.collector.vehicle-manager.http.poll-interval-ms:1000}")
public void collectUnmannedVehicleData() {
if (collectorDisabled) {
return;
}
// 丢弃旧轮次上一轮未完成时跳过避免多车循环HTTP + fixedRate + @Async堆积
if (!unmannedCollectInProgress.compareAndSet(false, true)) {
log.warn("无人车状态采集上一轮尚未完成,跳过本轮以避免堆积(保持实时性)");
return;
}
try {
if (unmannedVehicleIds.isEmpty()) {
// 启动时可能尚未刷新到列表这里做一次快速拉取作为兜底
@ -883,8 +858,6 @@ public class DataCollectorService {
} catch (Exception e) {
log.error("采集无人车数据异常", e);
} finally {
unmannedCollectInProgress.set(false);
}
}

View File

@ -34,7 +34,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.qaup.collision.datacollector.dao.DataCollectorDao;
@ -99,8 +98,6 @@ public class DataProcessingService {
* 防止@Scheduled任务重入导致并发执行消息风暴与数据库压力
* 固定频率调度在任务执行时间超过间隔时可能出现并发重入
*/
private final AtomicBoolean periodicProcessingInProgress = new AtomicBoolean(false);
/**
* 设置活跃对象缓存的引用由DataCollectorService调用
*/
@ -121,21 +118,13 @@ public class DataProcessingService {
* 7. 执行违规检测
* 8. 保存无人车数据到数据库
*/
@Scheduled(fixedRateString = "${data.collector.detection.interval:1000}")
// Fixed-delay scheduling prevents overlap without dropping cycles.
@Scheduled(fixedDelayString = "${data.collector.detection.interval:1000}")
@Transactional
public void performPeriodicDataProcessing() {
if (collectorDisabled) {
return;
}
// 丢弃旧轮次如果上一轮尚未完成直接跳过本轮以保证实时性
if (!periodicProcessingInProgress.compareAndSet(false, true)) {
log.warn("周期性数据处理上一轮尚未完成,跳过本轮以避免重入(保持实时性)");
return;
}
try {
if (activeMovingObjectsCache == null || activeMovingObjectsCache.isEmpty()) {
log.debug("活跃对象缓存为空,仅处理航班通知/路由重试后返回");
// 航班通知与路由下发不依赖活跃对象列表避免因为无移动对象而错过路由重试
@ -171,10 +160,6 @@ public class DataProcessingService {
saveUnmannedVehicleDataPeriodically(currentActiveObjects);
log.info("周期性数据处理完成");
} finally {
periodicProcessingInProgress.set(false);
}
}
/**