1. 项目概述
校园美食交流系统是一个基于SSM框架开发的Web应用,旨在为高校学生提供一个分享、发现和评价校园周边美食的社交平台。这个系统解决了学生在陌生校园环境中"吃什么"的痛点,通过用户生成内容(UGC)的方式构建校园美食数据库。
我在开发过程中发现,这类系统最核心的价值在于激发学生的分享欲望。与商业点评平台不同,校园美食交流更注重真实性和同学间的信任感。系统采用了轻量级架构,确保在学生社团有限的服务器资源下也能稳定运行。
2. 技术架构解析
2.1 SSM框架选型
采用Spring+SpringMVC+MyBatis的组合主要基于以下考量:
- Spring的IoC容器管理业务对象依赖关系,通过注解配置简化了Bean管理
- SpringMVC的拦截器非常适合处理校园网环境下的高频短连接
- MyBatis的灵活性可以应对频繁变更的美食数据模型
数据库选用MySQL 5.7,配置了主从复制确保高峰时段的查询性能。这里有个细节:我们在my.cnf中特别调整了innodb_buffer_pool_size,因为美食图片的BLOB字段会占用较大内存。
2.2 核心数据模型设计
系统包含5个主要实体:
- 用户表(t_user):存储学生认证信息
- 美食表(t_food):记录菜品基本信息
- 店铺表(t_shop):维护商家数据
- 评价表(t_review):用户点评内容
- 收藏表(t_favorite):用户收藏关系
特别注意了反范式设计:在t_food表中冗余了店铺名称字段,虽然增加了存储空间,但显著减少了列表页的联表查询。
3. 关键功能实现
3.1 基于位置的店铺推荐
利用百度地图API实现校区电子围栏,通过Geohash算法对店铺坐标编码。核心SQL如下:
sql复制SELECT * FROM t_shop
WHERE geohash LIKE 'wx4er%'
ORDER BY avg_score DESC
LIMIT 10
实际测试发现,在1km范围内Geohash前缀取6位时查询效率最佳。这个距离正好覆盖大多数高校的周边商圈。
3.2 防刷评机制
针对学生群体中可能出现的恶意刷评行为,实现了三级防御:
- 基础规则:同一用户对同一店铺每天限评1次
- 行为分析:检测短时间内的连续操作
- 人工审核:敏感词触发人工复核
在Spring拦截器中这样实现频次控制:
java复制@Around("execution(* com..ReviewService.addReview(..))")
public Object checkFrequency(ProceedingJoinPoint pjp) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getRemoteAddr();
if(redisTemplate.opsForValue().get(ip) != null){
throw new RateLimitException();
}
return pjp.proceed();
}
4. 性能优化实践
4.1 缓存策略设计
采用Redis多级缓存方案:
- 一级缓存:MyBatis本地缓存(会话级别)
- 二级缓存:Redis集群,缓存热点数据
- 特殊处理:对榜单类数据设置不同的过期时间
发现美食排行榜适合用ZSET实现:
java复制// 更新评分
redisTemplate.opsForZSet().add(
"food:rank",
foodId,
newScore
);
// 查询TOP10
Set<Object> tops = redisTemplate.opsForZSet()
.reverseRange("food:rank", 0, 9);
4.2 图片处理优化
学生上传的菜品图片存在两个问题:
- 体积过大(平均3-5MB)
- 尺寸不统一
解决方案:
- 使用Thumbnailator进行客户端压缩
- 服务端转存为WebP格式
- CDN分发缩略图
实测将1920x1080的JPEG转换为800x600的WebP后,体积减少82%而画质损失不明显。
5. 部署与运维
5.1 校园网环境适配
高校网络通常有以下特点:
- IPv6优先
- 出站端口限制
- 夜间断电断网
应对措施:
- 双栈部署(IPv4/IPv6)
- 使用80/443标准端口
- 增加凌晨3点的自动备份任务
5.2 监控方案
由于预算有限,采用Prometheus+Grafana自建监控:
- 关键指标:API响应时间、并发用户数
- 自定义指标:菜品新增速率
- 告警规则:当500错误率>1%时触发
配置示例:
yaml复制rules:
- alert: HighErrorRate
expr: rate(http_server_requests_errors_total[1m]) > 0.01
for: 5m
6. 运营数据分析
系统运行半年后,我们发现了一些有趣现象:
- 评价高峰集中在周五晚上(20:00-22:00)
- "辣度"是学生最常提到的关键词
- 人均15-20元的店铺收藏量最高
- 90%的用户通过移动端访问
这些数据指导我们优化了推荐算法,将时间因素和价格区间作为重要权重。
7. 安全防护措施
针对校园系统的特殊安全需求,我们实施了:
- 统一身份认证对接
- 敏感操作二次验证
- XSS过滤
- 定期漏洞扫描
在Spring Security配置中特别注意了CSRF防护:
java复制@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.requireCsrfProtectionMatcher(
new RequestMatcher() {
private final Pattern allowedMethods =
Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
@Override
public boolean matches(HttpServletRequest request) {
return !allowedMethods.matcher(
request.getMethod()).matches();
}
});
}
8. 项目演进方向
根据用户反馈,下一步计划开发:
- 外卖比价功能:聚合多个平台价格
- 食堂档口实时排队监测
- 美食卡路里计算器
- 社团订餐拼单系统
特别是在食堂排队功能上,我们正在测试基于WiFi探针的人数统计方案,初步测试准确率可达85%以上。