一、方案核心设计
通过配置驱动 + 内存计算实现准实时聚合,完全基于现有技术栈(无需新增中间件)
graph TD
A[设备数据] --> B[PG原始表]
B --> C{定时聚合任务}
C --> D[Java Cache]
D --> E[数据展示接口]
二、技术选型对照表
| 组件 | 选型 | 实现 |
|---|---|---|
| 定时任务 | Hutool CronUtil | CronUtil.schedule() |
| 聚合计算 | SQL + Java 内存处理 | commonQuery方法 |
| 缓存 | Caffeine/Guava Cache | Cache管理 |
| 配置管理 | PG配置表 | ins_stat_monitor_config |
三、关键代码实现
// Caffeine缓存+并行计算
private LoadingCache<String, AggResult> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.SECONDS) // 数据10秒过期
.build(k -> computeAgg(k));
@Scheduled(fixedRate = 5000) // 每5秒触发
public void batchAggregate() {
configs.parallelStream().forEach(config -> { // 并行处理
AggResult result = jdbcTemplate.query(config.getSql(), rowMapper);
cache.put(config.getChartId(), result);
});
}
四、性能优化策略
| 场景 | 优化手段 | 效果 |
|---|---|---|
| 高并发查询 | 缓存分层:本地缓存(Caffeine)+ 分布式Redis(可选) | 提升读取吞吐量 3-5倍 |
| 大数据量聚合 | PG分页查询 + Java流式处理 | 降低单次内存占用 70% |
| 定时任务过载 | 动态调整调度频率(根据负载自动缩放) | CPU利用率稳定在 60%以下 |
五、方案特性
| 特性 | 方案 |
|---|---|
| 实时性 | 固定5秒间隔(准实时) |
| 内存管理 | Caffeine自动回收,可控 |
| 扩展性 | 完全配置驱动,无需发布 |
| 资源消耗 | 并行流+批量提交,资源利用率高 |
六、实施步骤
-
环境准备
# 添加依赖(pom.xml) <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>3.1.8</version> </dependency> -
配置表结构调整
create table monitor_config ( id integer default nextval('monitor_config_id_seq'::regclass) not null, chart_id varchar(100), chart_name varchar(100), data_source varchar(3), query_sql text, calc_script text, handle_script text, special_handle text, refresh_gap integer, query_gap integer, update_cron varchar not null, catch_flag varchar(3), del_flag varchar(3) default 0, description varchar(1000) ); comment on table t_stat_monitor_config is '监控配置'; comment on column t_stat_monitor_config.id is '主键'; comment on column t_stat_monitor_config.chart_id is '图表唯一编码'; comment on column t_stat_monitor_config.chart_name is '图表名'; comment on column t_stat_monitor_config.data_source is '数据源'; comment on column t_stat_monitor_config.query_sql is '查询sql'; comment on column t_stat_monitor_config.calc_script is '计算脚本'; comment on column t_stat_monitor_config.handle_script is '聚合脚本'; comment on column t_stat_monitor_config.special_handle is '特殊处理;无法使用sql的图形,会使用硬编码。标记类名'; comment on column t_stat_monitor_config.refresh_gap is '刷新间隔;秒数'; comment on column t_stat_monitor_config.query_gap is '查询间隔;秒数'; comment on column t_stat_monitor_config.update_cron is '缓存更新间隔cron参数'; comment on column t_stat_monitor_config.catch_flag is '缓存标记'; comment on column t_stat_monitor_config.del_flag is '删除标识'; comment on column t_stat_monitor_config.description is '描述'; alter table t_stat_monitor_config add primary key (id);ALTER TABLE ins_stat_monitor_config ADD COLUMN agg_interval INT DEFAULT 5; -- 聚合间隔(秒) -
核心服务改造
public class AggService { @Autowired private JdbcTemplate jdbcTemplate; private LoadingCache<String, AggResult> cache; @PostConstruct public void init() { cache = Caffeine.newBuilder() .refreshAfterWrite(5, TimeUnit.SECONDS) .build(this::loadFromDB); // 动态定时任务(根据配置表agg_interval字段) CronUtil.schedule("dynamic_agg", "0/5 * * * * ?", () -> { refreshAllCache(); }); } private AggResult loadFromDB(String chartId) { String sql = getSqlFromConfig(chartId); return jdbcTemplate.queryForObject(sql, AggResult.class); } }
七、监控指标看板
| 指标 | 采集方式 | 告警阈值 |
|---|---|---|
| 缓存命中率 | Caffeine内置统计 | <90% 触发警告 |
| 聚合延迟 | 打点记录处理时间戳 | >5秒 触发严重告警 |
| PG连接池使用率 | 监控Druid数据源 | >80% 扩容连接池 |
八、方案局限性
| 问题 | 应对策略 |
|---|---|
| 数据时效性不足 | 降低聚合间隔(最低1秒) + PG流式结果集 |
| 历史数据无法回溯 | 定期快照缓存数据到PG历史表 |
| 集群环境部署困难 | 改用Redis分布式锁协调多节点任务 |
总结
该方案通过 「配置驱动」+「内存计算」+「轻量调度」 实现准实时聚合,适用于中小规模物联网场景(日增数据量<1亿)。建议初期采用单节点部署,随业务增长逐步引入Redis和Flink增强实时处理能力。