1. 项目背景与需求分析
校园人员进出登记管理是每所高校都必须面对的日常管理工作。传统的手工登记方式存在诸多痛点:纸质登记表容易丢失损坏、访客排队等待时间长、数据统计困难、夜间值班人员工作负担重。特别是在疫情期间,进出人员的健康信息登记更是让这项工作变得复杂。
我们团队为某高校开发的这套系统,采用SpringBoot后端+微信小程序的架构,实现了以下核心功能:
- 教职工/学生通过微信扫码快速完成身份核验
- 外来访客在线预约登记,到校时扫码确认
- 实时统计各时段人流量数据
- 异常出入行为自动预警
- 与学校OA系统的人员数据实时同步
实际部署后发现,相比原来的手工登记,平均通行时间从90秒缩短到8秒,值班人员工作量减少70%,疫情期间的流调效率提升显著。
2. 技术架构设计
2.1 整体技术栈选型
后端采用SpringBoot 2.7.x版本,主要基于以下考虑:
- 快速开发:自动配置特性大幅减少XML配置
- 内嵌Tomcat:避免单独部署Web服务器
- 丰富的Starter:轻松集成MyBatis、Redis等组件
- 健康检查:配合K8s实现优雅启停
前端选择微信小程序而非原生App:
- 零安装成本:直接扫码即可使用
- 开发成本低:一套代码适配iOS/Android
- 微信生态:天然集成扫码、消息通知能力
graph TD A[微信小程序] -->|HTTPS| B(SpringBoot) B --> C[MySQL] B --> D[Redis] B --> E[学校LDAP] C --> F[数据报表]2.2 核心组件说明
身份认证模块
- 教职工/学生:对接学校LDAP系统
- 访客:身份证OCR识别+活体检测
- 采用JWT+双Token机制保障安全
进出记录模块
- 基于地理围栏技术判断真实进出
- 使用Redis Geo存储位置数据
- 进出事件触发MQ消息通知
数据统计模块
- 使用Elasticsearch聚合分析
- 定时任务生成日报/周报
- 对接学校数据中台
3. 关键实现细节
3.1 双Token认证机制
为解决小程序长期登录的安全问题,我们实现如下流程:
// 登录接口示例 @PostMapping("/login") public Result login(@RequestBody LoginDTO dto) { // 1. 验证用户身份 User user = authService.verify(dto.getCode()); // 2. 生成双token String accessToken = JwtUtil.generate(user, 2 * 60 * 60); // 2小时过期 String refreshToken = JwtUtil.generate(user, 7 * 24 * 60 * 60); // 7天过期 // 3. 记录token关系 redisTemplate.opsForValue().set( "refresh:"+user.getId(), accessToken, 7, TimeUnit.DAYS); return Result.success() .put("accessToken", accessToken) .put("refreshToken", refreshToken); }实际开发中发现,iOS系统在后台超过5分钟后会断开WebSocket连接,需要客户端定时发送心跳包保持活跃。
3.2 高并发进出记录处理
采用多级缓存策略应对上下课高峰期:
- 第一层:本地Caffeine缓存(有效期10秒)
- 第二层:Redis集群(有效期1分钟)
- 最终写入:MySQL分库分表
@Transactional public void addAccessRecord(AccessRecord record) { // 1. 写入本地队列 kafkaTemplate.send("access-log", new ObjectMapper().writeValueAsString(record)); // 2. 更新实时统计 redisTemplate.opsForZSet() .incrementScore("realTimeAccess", record.getGateId(), 1); }4. 性能优化实践
4.1 小程序发热问题解决
通过性能分析发现两个主要问题:
地图组件过度渲染
- 解决方案:改用自定义canvas绘制
- 效果:CPU占用率从75%降至32%
频繁的setData调用
- 优化前:每次定位更新都触发渲染
- 优化后:采用差异对比算法,200ms节流
// 优化后的定位处理 let lastData = null const onLocationChange = throttle((data) => { if(!isEqual(data, lastData)) { this.setData({location: data}) lastData = deepClone(data) } }, 200)4.2 后端接口优化
Nginx配置调优
# 启用gzip压缩 gzip on; gzip_min_length 1k; gzip_types application/json; # 调整keepalive keepalive_timeout 30s; keepalive_requests 100;SpringBoot参数调整
# 修改Tomcat参数 server.tomcat.max-threads=200 server.tomcat.accept-count=50 # 启用响应压缩 server.compression.enabled=true
5. 安全防护措施
5.1 防爬虫方案
- 接口签名验证
- 滑动验证码
- 请求频率限制(Redis实现)
@RateLimiter(value = 10, key = "#ip") @GetMapping("/api") public Result getData(String ip) { //... }
5.2 敏感数据保护
数据库字段加密
- 使用国密SM4算法
- 密钥通过KMS管理
日志脱敏处理
@Bean public PatternLayoutEncoder encoder() { PatternLayoutEncoder encoder = new PatternLayoutEncoder(); encoder.setPattern("%msg%replace(%msg){'\\d{11}','***'}"); return encoder; }
6. 部署与监控
6.1 K8s部署方案
apiVersion: apps/v1 kind: Deployment metadata: name: campus-access spec: replicas: 3 template: spec: containers: - name: app image: registry.cn-hangzhou.aliyuncs.com/edu/campus-access:1.2.0 resources: limits: cpu: "2" memory: 2Gi livenessProbe: httpGet: path: /actuator/health port: 80806.2 监控体系搭建
Prometheus采集指标
- JVM内存使用
- 接口响应时间
- 数据库连接池状态
Grafana监控大屏
- 实时进出人数
- 系统健康状态
- 异常行为告警
7. 项目演进方向
AI人脸识别升级
- 当前:静态图片比对
- 规划:动态视频流分析
物联网设备对接
- 门禁控制器集成
- 体温检测设备联动
大数据分析
- 人员行为模式分析
- 疫情传播链预测
在三个月运行期间,系统日均处理进出记录2.3万条,高峰期QPS达到150,平均响应时间87ms。通过这个项目,我们总结出三点重要经验:
- 小程序端必须做好性能测试,特别是iOS设备的后台运行限制
- 进出记录这类高频写入场景,要采用异步化处理架构
- 学校IT环境通常较复杂,对接各系统时需要充分预留兼容时间