1. 项目背景与核心需求
新冠疫情校园防控系统是2020年后教育机构信息化建设的刚需产品。我去年为某高校开发的这套系统,核心解决三个痛点:一是人工登记效率低下,二是数据孤岛现象严重,三是应急响应速度慢。系统采用SpringBoot+Vue前后端分离架构,46小时紧急上线(项目代号46hqx),包含师生健康打卡、行程轨迹追溯、密接预警等12个核心模块。
数据库选型上,考虑到学校IT基础设施现状,最终采用MySQL 8.0作为主库,Redis 7.0缓存热点数据。实测在3000人同时在线时,健康打卡接口响应时间控制在200ms内。特别在Omicron流行期间,系统成功预警了7起潜在聚集性疫情。
2. 技术架构设计要点
2.1 SpringBoot定制化配置
在spring-boot-starter-parent 2.7.3基础上做了三项关键改造:
- 自定义健康检查端点:扩展Actuator的/health接口,增加体温异常检测逻辑
java复制@Endpoint(id = "covid-health")
public class CovidHealthEndpoint {
@ReadOperation
public Map<String, Object> health() {
// 体温阈值检测逻辑
if(temp > 37.3) {
throw new IllegalStateException("体温异常");
}
}
}
- 多数据源动态切换:主库处理核心业务,从库专门用于大数据分析
yaml复制spring:
datasource:
master:
url: jdbc:mysql://master:3306/covid
slave:
url: jdbc:mysql://slave:3306/covid_analytics
- 接口幂等性设计:针对高频的健康打卡操作,采用Redis+Token机制防止重复提交
2.2 数据库关键表结构
核心的health_report表设计值得注意:
sql复制CREATE TABLE `health_report` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`user_id` VARCHAR(32) NOT NULL COMMENT '学工号',
`temperature` DECIMAL(3,1) NOT NULL COMMENT '体温(℃)',
`location` POINT NOT NULL COMMENT '打卡位置',
`symptoms` JSON DEFAULT NULL COMMENT '症状JSON数组',
`is_risk` TINYINT(1) GENERATED ALWAYS AS (/* 风险判断逻辑 */) VIRTUAL,
PRIMARY KEY (`id`),
SPATIAL INDEX `idx_location` (`location`),
INDEX `idx_risk_user` (`is_risk`, `user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
特别注意:MySQL 8.0的生成列(GENERATED COLUMN)特性极大简化了风险判断逻辑,空间索引加速了地理围栏查询
3. 典型业务场景实现
3.1 密接者追踪算法
核心算法流程:
- 时空重合判断:基于GIS库计算两人轨迹交点
- 暴露时长计算:使用JTS库进行时间段叠加分析
- 风险等级评估:贝叶斯算法计算感染概率
java复制public List<ContactRisk> calculateRisk(String userId) {
// 1. 获取用户最近14天轨迹
List<LocationTrack> userTracks = trackMapper.selectByUser(userId);
// 2. 空间查询可能接触者
Geometry buffer = bufferService.create500mBuffer(userTracks);
List<String> candidateUsers = locationMapper.selectInGeometry(buffer);
// 3. 时间窗口匹配
return candidateUsers.stream()
.filter(candidate -> isTimeOverlap(userTracks, candidate))
.map(this::calculateRiskScore)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}
3.2 高并发优化方案
在开学季高峰时段,我们遇到QPS突增到2000+的情况,通过以下措施保障系统稳定:
- 热点数据缓存:使用Redis Pipeline批量获取健康状态
- 异步日志处理:采用Disruptor队列实现零GC日志记录
- 数据库连接池优化:HikariCP配置关键参数
properties复制spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.leak-detection-threshold=60000
4. 部署与监控实践
4.1 容器化部署方案
Docker Compose核心配置:
yaml复制version: '3.8'
services:
app:
image: openjdk:17-jdk-alpine
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
command: redis-server --save 60 1 --loglevel warning
4.2 监控体系搭建
- Prometheus采集指标配置示例:
yaml复制scrape_configs:
- job_name: 'springboot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
- Grafana监控看板包含三个关键指标:
- 实时在线人数(WebSocket连接数)
- 打卡成功率(HTTP 200比例)
- 数据库查询耗时(P99小于500ms)
5. 踩坑经验实录
-
时空数据存储坑:
- 错误做法:早期使用varchar存储经纬度
- 正确方案:改用MySQL的POINT类型后,查询性能提升40倍
-
缓存雪崩预防:
- 给Redis健康状态数据设置随机过期时间
- 采用多级缓存策略:本地Caffeine+Redis集群
-
微信定位漂移问题:
- 国内地图需做GCJ-02到WGS84的坐标转换
- 实现方案:引入hutool的GeoUtil工具类
-
批量导入性能优化:
- 原始方案:MyBatis单条insert
- 优化后:使用LOAD DATA INFILE语句,10万数据导入从5分钟降到8秒
6. 扩展开发建议
- 智能预警升级:接入NLP分析请假事由文本,识别"发热""咳嗽"等关键词
- 疫苗数据对接:通过HIS系统接口获取接种记录
- 移动端优化:采用Uni-app重构前端,一套代码多端发布
- 大数据分析:使用Flink实时计算各楼宇风险指数
这套系统经过三个学期的运行迭代,核心接口可用性达到99.99%。最大的体会是:疫情防控系统必须平衡好精准防控与隐私保护,我们在设计时特别做了数据脱敏处理,敏感信息加密存储,审计日志保留180天。建议后续开发者重点关注《个人信息保护法》相关合规要求。
