一、背景与目标
1.1 原始系统定位
DataSyncManager 是 Android 应用中用于统一管理数据同步任务的核心组件,设计上充分考虑了:
- 并发控制
- 资源复用
- 失败追踪
- 日志记录
- 优先级调度
其核心目标是:
在资源受限的 Android 设备上,安全、高效、可靠地执行多类型数据同步任务(手动/自动),避免并发冲突,保障数据一致性,并提供可观测性。
1.2 迁移目标
将该组件的核心思想迁移到 Spring Boot 后端服务,实现:
- 利用 Spring Boot 的依赖注入、配置管理、事务控制等能力;
- 保留增量同步、幂等性、失败重试、可观测性等关键逻辑;
- 支持灵活扩展(多种数据源)、集群部署与监控告警。
二、Android 版 DataSyncManager 核心设计解析
2.1 单例模式(Singleton)
- 使用双重检查锁(DCL)实现线程安全懒加载。
- 全局唯一实例,避免状态混乱。
2.2 线程池复用
- 复用
AppExecutors.get().io()的 IO 线程池,节省资源。 - 提供
executeTask()/executeAsync()对外异步能力。
2.3 并发控制:双标志位 + ReentrantLock
isManualSyncing/isAutoSyncing:AtomicBoolean 标记同步状态。syncLock:ReentrantLock 保证 6 类任务串行执行。- 优先级策略:
- 手动同步:高优先级,排队等待当前自动任务完成;
- 自动同步:低优先级,若手动进行中则跳过。
2.4 任务解耦:入队而非直接执行
-
同步任务仅构造
SyncTask并存入数据库; -
实际网络请求由
SyncWorker(基于 WorkManager)后台执行,支持:
- 断网重试
- 网络条件约束
- 生命周期安全
2.5 精细化日志与失败追踪
ActivationLogger
记录:
-
子任务生命周期(开始、入队、异常)
-
同步总览(成功/失败数)
-
连续失败次数、最后失败时间
-
告警策略:
- ≥3 次失败 → 警告
- ≥10 次失败 → 严重告警
2.6 同步数据覆盖全面(6 类)
- 激活日志(文本)
- RFID 验证事件(DB 表)
- RFID 白名单 & 租户详情(下行配置)
- 药瓶表(DB 表)
- 设备参数(SharedPreferences + DB)
- 功率曲线(带 JSON 曲线)
→ 覆盖上行上报与下行配置全链路。
2.7 健壮性设计
- 异常隔离:每个子任务独立 try-catch;
- 降级机制:线程池不可用时 fallback 到
new Thread(); - 空值防护:大量判空(如
latestStock != null); - 数据过滤:跳过无效数据(如空
curveJson)。
三、能否迁移到 Spring Boot?------ 可行性分析
✅ 可以迁移,但需重构,部分 Android 特有机制不再适用。
| Android 特性 | Spring Boot 适配建议 |
|---|---|
| 单例模式 | 用 @Service(默认单例)替代 |
| 线程池复用 | 使用 @Async + 自定义 TaskExecutor |
| WorkManager / SyncWorker | 替换为 @Async + Spring Retry,或消息队列(Kafka/RabbitMQ) |
| SharedPreferences | 改用数据库配置表 或 @ConfigurationProperties |
| ReentrantLock 串行控制 | 单机可用 synchronized;集群需 Redis 分布式锁(按设备 ID) |
| AtomicBoolean 并发标志 | 单机可用 volatile boolean;集群需分布式状态存储 |
| 文件日志(ActivationLogger) | 改用 SLF4J + ELK/Prometheus/Grafana |
| 失败计数存本地 | 改存数据库或 Redis |
💡 结论 :
"形不可照搬,神值得继承" ------ 保留其协调流程、失败追踪、防并发冲突、可观测性的设计哲学,用 Spring 生态重新实现。
四、Spring Boot 迁移方案设计
4.1 架构分层重构
原 Android "大管家"模式 → 拆分为:
| 组件 | 职责 |
|---|---|
DataSyncOrchestrator |
协调同步流程(原 Manager) |
SyncTaskRepository |
管理待同步任务(对应原 SyncTaskDao) |
SyncTaskProcessor |
异步执行上传(替代 SyncWorker) |
FailureTracker |
独立服务,处理失败计数与告警 |
4.2 并发模型升级
- Android:单进程,靠锁控制。
- Spring Boot :可能多实例 → 必须使用分布式锁 (如 Redis + Redlock)确保同一设备的同步互斥。
4.3 数据源统一
- 不再混合使用 Room + SharedPreferences + 文件;
- 统一使用关系型数据库(MySQL/PostgreSQL)或 NoSQL(MongoDB)。
4.4 日志与监控现代化
- 使用 MDC 注入
traceId/deviceId; - 日志接入 ELK 或 Loki;
- 指标上报 Prometheus(同步次数、耗时、失败率);
- 告警对接 AlertManager / 企业微信 / 钉钉。
五、Spring Boot 实现示例
5.1 项目结构建议
src/
├── main/
│ ├── java/com.example.sync/
│ │ ├── DataSyncOrchestrator.java // 核心协调器
│ │ ├── config/SyncConfig.java // 配置绑定
│ │ ├── service/FailureTracker.java // 失败追踪
│ │ ├── datasource/
│ │ │ ├── SourceReader.java
│ │ │ └── TargetWriter.java
│ │ └── task/SyncTaskProcessor.java // 异步任务执行
│ └── resources/application.yml
5.2 配置类
java
@Configuration
@ConfigurationProperties(prefix = "sync")
@Data
public class SyncConfig {
private boolean enabled = true;
private int batchSize = 100;
private String lastSyncTime;
private Retry retry = new Retry();
@Data
public static class Retry {
private int maxAttempts = 3;
private long delayMs = 5000;
}
}
5.3 核心协调器(简化版)
java
@Service
@Slf4j
public class DataSyncOrchestrator {
private final SyncConfig config;
private final SourceReader<?> reader;
private final TargetWriter<?> writer;
private volatile Instant lastSyncTime;
// 构造注入...
@Transactional
public void performSync(String deviceId) {
// 1. 获取分布式锁(Redis,key = "sync:lock:" + deviceId)
// 2. 拉取增量数据
// 3. 异步提交到 SyncTaskProcessor(或直接调用 FeignClient)
// 4. 成功则更新 lastSyncTime;失败则 FailureTracker.record(deviceId)
}
}
5.4 异步任务处理(替代 WorkManager)
java
@Component
public class SyncTaskProcessor {
@Async
@Retryable(value = {Exception.class}, maxAttempts = 3, backoff = @Backoff(delay = 5000))
public void uploadData(SyncTask task) {
// 调用远程 API
// 成功 → 标记为 UPLOADED
// 失败 → 抛出异常触发重试
}
}
需启用:
@EnableAsync+@EnableRetry
5.5 定时同步(可选)
java
@Component
public class SyncScheduler {
@Scheduled(fixedDelay = 300_000) // 5分钟
public void syncAllDevices() {
// 查询所有活跃设备,触发 performSync(deviceId)
}
}
六、关键特性对比与保障
| 特性 | Android 实现 | Spring Boot 实现 |
|---|---|---|
| 单例 | DCL 单例 | @Service |
| 并发控制 | ReentrantLock + AtomicBoolean | Redis 分布式锁 |
| 任务执行 | WorkManager | @Async + Spring Retry / MQ |
| 配置存储 | SharedPreferences | DB / Config Server |
| 失败追踪 | 本地计数 + 文件日志 | DB/Redis + Prometheus + 告警 |
| 可观测性 | ActivationLogger | SLF4J + MDC + Metrics |
七、总结与建议
✅ 优势继承
- 职责清晰:协调者 vs 执行者分离;
- 健壮可靠:失败重试、异常隔离、幂等写入;
- 可观测性强:日志、指标、告警三位一体。
🔧 迁移建议
- 不要直接复制代码,而是提取"同步编排逻辑";
- 优先使用 Spring 原生能力(@Async, @Retryable, @Transactional);
- 集群环境必须引入分布式锁,避免多实例并发同步同一设备;
- 失败状态持久化到 DB/Redis,而非内存或本地文件;
- 结合 Micrometer + Prometheus 实现生产级监控。
📌 最终目标 :
构建一个可配置、可监控、可扩展、高可用的企业级数据同步服务,服务于 IoT 设备、边缘计算节点或跨系统数据对账场景。