mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-05-04 18:10:10 +08:00
update finalize ykc offline fix baseline
This commit is contained in:
@@ -165,7 +165,11 @@ public class PileChannelEntity {
|
||||
if (!StringUtils.equals(currentChannelId, expectedChannelId)) {
|
||||
return false;
|
||||
}
|
||||
return manager.remove(pileSn, currentCtx);
|
||||
boolean removed = manager.remove(pileSn, currentCtx);
|
||||
if (removed) {
|
||||
channelIdToPileSnMap.remove(expectedChannelId);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
public static List<String> getPileSnListSnapshot() {
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ThreadPoolConfig {
|
||||
// 最大可创建的线程数
|
||||
private final int maxPoolSize = 128; // 突发时翻倍,避免过多上下文切换
|
||||
|
||||
// 队列最大长度 (优化:增大队列容量以应对桩端消息高峰)
|
||||
// 队列最大长度
|
||||
private final int queueCapacity = 5000; // 桩消息短时堆积时提供缓冲,防止直接拒绝
|
||||
|
||||
// 线程池维护线程所允许的空闲时间
|
||||
@@ -51,7 +51,6 @@ public class ThreadPoolConfig {
|
||||
|
||||
/**
|
||||
* 线程池
|
||||
* 优化:使用 DiscardOldestPolicy 避免阻塞调用者线程(如 Netty IO 线程)
|
||||
*/
|
||||
@Bean(name = "threadPoolTaskExecutor")
|
||||
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
|
||||
@@ -61,8 +60,8 @@ public class ThreadPoolConfig {
|
||||
executor.setQueueCapacity(queueCapacity);
|
||||
executor.setKeepAliveSeconds(keepAliveSeconds);
|
||||
// 线程池对拒绝任务(无线程可用)的处理策略
|
||||
// 优化:DiscardOldestPolicy 丢弃最老的任务,避免阻塞调用者线程
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
// 关键链路任务不能静默丢弃,回退为调用方执行
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
executor.setThreadNamePrefix(threadNamePrefix);
|
||||
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
// log.info("threadPoolTaskExecutor创建成功");
|
||||
|
||||
@@ -64,19 +64,16 @@ public class HeartbeatRequestHandler extends AbstractYkcHandler {
|
||||
String connectorStatus = BytesUtil.binary(connectorStatusByte, 16);
|
||||
// log.info("桩号:{}, 枪号:{}, 枪状态:{}", pileSn, pileConnectorNum, connectorStatus);
|
||||
|
||||
// 优化:先构建并返回心跳应答,不阻塞心跳回复
|
||||
// 先构建心跳应答,再同步刷新最后通信时间和连接映射,保证离线确认链路及时收敛
|
||||
byte[] flag = Constants.zeroByteArray;
|
||||
byte[] messageBody = Bytes.concat(pileSnByte, pileConnectorNumByte, flag);
|
||||
byte[] response = getResult(ykcDataProtocol, messageBody);
|
||||
|
||||
// 优化:所有其他操作(Redis、数据库)完全异步化,不阻塞心跳回复
|
||||
// 将 saveLastTimeAndCheckChannel 和 updateStatus 都改为异步执行
|
||||
saveLastTimeAndCheckChannel(pileSn, channel);
|
||||
|
||||
// 数据库状态更新继续异步,避免把心跳回包链路拖长
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
// 异步保存连接时间并检查通道(Redis 操作)
|
||||
saveLastTimeAndCheckChannel(pileSn, channel);
|
||||
|
||||
// 异步更新状态(数据库操作)
|
||||
String frameType = BytesUtil.bcd2Str(ykcDataProtocol.getFrameType());
|
||||
pileBasicInfoService.updateStatus(frameType, pileSn, pileConnectorNum, connectorStatus, null);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -88,8 +88,11 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-001
|
||||
|
||||
- 优先级:P0
|
||||
- 状态:todo
|
||||
- 状态:done
|
||||
- 目标:将云快充连接保活从“30 秒空闲直接断开”改为“允许短时抖动,按连续丢心跳或宽限期判定断链”。
|
||||
- 当前进展:
|
||||
- 已按第一批止血方案落地为 `15s tick + 连续 3 次 READER_IDLE 才关闭`。
|
||||
- 已补 `idleCount / lastFrameType / lastReceiveAt / lastSerialNumber / disconnectReason` 连接属性。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerChannelInitializer.java`
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java`
|
||||
@@ -106,8 +109,11 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-002
|
||||
|
||||
- 优先级:P0
|
||||
- 状态:todo
|
||||
- 状态:done
|
||||
- 目标:增加“断链宽限期”,避免瞬断立刻将枪口置离线、订单置异常。
|
||||
- 当前进展:
|
||||
- 已落地 `60s` 离线确认宽限期。
|
||||
- 已引入 `pile_pending_disconnect` 和 `pile_offline_confirmed` 标记,并在恢复通信后自动清理。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java`
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java`
|
||||
@@ -124,8 +130,11 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-003
|
||||
|
||||
- 优先级:P0
|
||||
- 状态:todo
|
||||
- 状态:in_progress
|
||||
- 目标:补齐连接生命周期日志,支持“凌晨离线”专项排查。
|
||||
- 当前进展:
|
||||
- 已补空闲告警、连续空闲关闭、异常断链、宽限恢复、正式离线确认等主链路日志。
|
||||
- `LoginRequestHandler` / `UploadRealTimeMonitorHandler` 维度的专项日志尚未单独补齐。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java`
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/HeartbeatRequestHandler.java`
|
||||
@@ -142,8 +151,11 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-004
|
||||
|
||||
- 优先级:P0
|
||||
- 状态:todo
|
||||
- 状态:done
|
||||
- 目标:修复 channel 映射清理不完整的问题,避免旧连接残留。
|
||||
- 当前进展:
|
||||
- 已补 `removeByPileSnAndChannelId()` 安全删除。
|
||||
- 已补 `channelId -> pileSn` 反向映射维护,并修复删除时的脏映射残留问题。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java`
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/PileChannelEntity.java`
|
||||
@@ -159,8 +171,11 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-005
|
||||
|
||||
- 优先级:P1
|
||||
- 状态:todo
|
||||
- 状态:in_progress
|
||||
- 目标:将桩离线判定从“任意枪状态为离线即整桩离线”改为“最近通信时间 + 枪状态 + 宽限期”的综合判定。
|
||||
- 当前进展:
|
||||
- 已完成 `checkPileOffLine()` 优先识别 `PILE_OFFLINE_CONFIRMED` 标记。
|
||||
- 仍未重写 `getPileStatus/getPileStatusV2` 的整桩聚合规则,暂按第一批止血范围保留现状。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileConnectorInfoServiceImpl.java`
|
||||
- 设计要点:
|
||||
@@ -195,8 +210,12 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
### YKC-007
|
||||
|
||||
- 优先级:P1
|
||||
- 状态:todo
|
||||
- 状态:done
|
||||
- 目标:补每日自动对时,降低跨天时钟漂移的影响。
|
||||
- 当前进展:
|
||||
- 已新增 `jsowellTask.dailyProofreadTimeForYkcV160()`。
|
||||
- 已补 `0x56` 下发记录和 `0x55` 应答记录。
|
||||
- 待上线时补 Quartz 任务配置。
|
||||
- 修改文件:
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/YKCPushCommandServiceImpl.java`
|
||||
- `/Users/guoqiusi/Workspace/jsowell-charger-web/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TimeCheckSettingResponseHandler.java`
|
||||
@@ -319,6 +338,23 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
- 订单异常处理若改为延迟确认,需防止漏处理真正断电或断网导致的异常订单。
|
||||
- 双实现收敛前,所有改动应明确打在老 Handler 链路上,避免误改新 Strategy 无法生效。
|
||||
|
||||
## 当前进度快照
|
||||
|
||||
- 更新时间:2026-03-21 11:14:17 +0800
|
||||
- `done`:
|
||||
- `YKC-001`
|
||||
- `YKC-002`
|
||||
- `YKC-004`
|
||||
- `YKC-007`
|
||||
- `in_progress`:
|
||||
- `YKC-003`
|
||||
- `YKC-005`
|
||||
- `todo`:
|
||||
- `YKC-006`
|
||||
- `YKC-008`
|
||||
- `YKC-009`
|
||||
- `YKC-010`
|
||||
|
||||
## 进度记录模板
|
||||
|
||||
```md
|
||||
@@ -338,6 +374,58 @@ created_at: 2026-03-21T08:48:24+08:00
|
||||
- 备注/风险:
|
||||
```
|
||||
|
||||
## 最终上线注意项
|
||||
|
||||
- 本次建议作为一个整体上线,包含:
|
||||
- 第一批凌晨离线止血。
|
||||
- `YKC-007` 云快充 1.6 每日自动对时。
|
||||
- 当前最终基线以“离线判定正确性优先”为准,同时保留必要性能优化:
|
||||
- 保留 `EchoServerHandler` 绑定 `businessGroup`。
|
||||
- 保留 `PileChannelEntity` 的 `channelId -> pileSn` 反向映射。
|
||||
- 保留 `NettyServerHandler` 的消息处理耗时监控。
|
||||
- 不采用“心跳全异步 + 公共线程池 DiscardOldestPolicy”组合。
|
||||
- 已确认的最终收口原则:
|
||||
- `HeartbeatRequestHandler` 中 `saveLastTimeAndCheckChannel()` 必须同步执行,保证任意上行立即刷新 `PILE_LAST_CONNECTION`,并立即清除 `PILE_PENDING_DISCONNECT / PILE_OFFLINE_CONFIRMED`。
|
||||
- `HeartbeatRequestHandler` 中 `updateStatus()` 继续异步执行,避免数据库操作拖长心跳回包链路。
|
||||
- `ThreadPoolConfig.threadPoolTaskExecutor` 保持 `CallerRunsPolicy`,避免关键任务被静默丢弃。
|
||||
- `PileChannelEntity.removeByPileSnAndChannelId()` 必须同步清理反向映射,避免旧连接脏数据残留。
|
||||
|
||||
### Quartz 配置建议
|
||||
|
||||
- 新增每日对时任务:
|
||||
- `invokeTarget`: `jsowellTask.dailyProofreadTimeForYkcV160()`
|
||||
- 不建议把任务压在 `00:00` 整点,建议放到低峰时段,例如 `03:15`。
|
||||
- 每日对时任务默认只扫描“当前有活连接的云快充 1.6 桩”,并按小间隔逐台发送,避免凌晨集中打满链路。
|
||||
|
||||
### 上线后重点观察
|
||||
|
||||
- 是否还出现“凌晨批量掉线后立刻落离线”的情况。
|
||||
- 是否能看到 `pile_pending_disconnect` 在恢复通信后于宽限期内被清除。
|
||||
- 是否出现“正式离线确认”日志明显下降。
|
||||
- 是否能看到 `0x56` 下发记录与 `0x55` 应答记录。
|
||||
- 是否持续出现 `【性能警告】` 日志堆积。
|
||||
|
||||
### 建议回归项
|
||||
|
||||
- 连续触发 1 次、2 次、3 次 `READER_IDLE`:
|
||||
- 预期仅第 3 次关闭连接。
|
||||
- 第 3 次空闲关闭后 60 秒内重连:
|
||||
- 预期不落 `OFF_NETWORK`,不改订单异常。
|
||||
- 第 3 次空闲关闭后 60 秒内未恢复:
|
||||
- 预期才正式落离线。
|
||||
- 手工执行一次 `jsowellTask.dailyProofreadTimeForYkcV160()`:
|
||||
- 预期仅对在线云快充 1.6 桩发对时。
|
||||
- 检查 `TimeCheckSettingResponseHandler`:
|
||||
- 预期能记录 `0x55` 对时应答及桩端回传时间。
|
||||
|
||||
### 编译验证记录
|
||||
|
||||
- 已执行:
|
||||
- `mvn -pl jsowell-quartz,jsowell-netty -am -DskipTests compile`
|
||||
- `mvn -pl jsowell-netty,jsowell-framework,jsowell-common -am -DskipTests compile`
|
||||
- 结果:
|
||||
- 通过。
|
||||
|
||||
## 当前建议
|
||||
|
||||
- 先以第一批任务为本周主线,尽快止住凌晨离线误判。
|
||||
|
||||
Reference in New Issue
Block a user