1. 项目概述与背景
在餐饮行业数字化转型浪潮中,我注意到一个有趣的现象:顾客平均花费在菜单上的决策时间高达8-12分钟,而商家则苦恼于30%的菜品点击集中在20%的热门菜品上。这个毕业设计项目正是为了解决这一行业痛点——通过SpringBoot构建的智能点餐推荐系统,实现用户与菜品的精准匹配。
系统采用B/S架构,后端基于SpringBoot 2.7 + MyBatis Plus,前端使用Vue 3 + Element Plus,数据库选用MySQL 8.0。区别于传统点餐系统,我们创新性地整合了:
- 基于用户行为的协同过滤推荐算法
- 实时更新的菜品热度排行榜
- 多维度菜品标签体系(辣度、烹饪方式、适用场景等)
- 用户画像动态生成机制
2. 核心技术选型解析
2.1 后端技术栈设计
选择SpringBoot作为核心框架主要基于三点考量:
- 快速迭代:内嵌Tomcat和自动配置特性,使项目搭建时间缩短60%以上
- 生态完整:Spring Data JPA + MyBatis Plus组合同时满足快速开发和复杂SQL需求
- 性能优化:通过二级缓存(Redis)和连接池(HikariCP)设计,实测QPS可达1200+
关键依赖配置示例:
xml复制<dependencies>
<!-- 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 推荐算法支持 -->
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.13.0</version>
</dependency>
</dependencies>
2.2 推荐算法实现方案
系统采用混合推荐策略:
-
基于用户的协同过滤(UserCF)
- 相似度计算采用改进的余弦相似度公式:
code复制sim(u,v) = ∑(r_u,i - r̄_u)(r_v,i - r̄_v) / (√∑(r_u,i - r̄_u)² * √∑(r_v,i - r̄_v)²) - 加入时间衰减因子:近期行为权重=原始权重×e^(-λΔt)
- 相似度计算采用改进的余弦相似度公式:
-
基于内容的推荐(CB)
- 菜品特征向量化:使用TF-IDF算法处理菜品描述文本
- 用户偏好模型:根据历史订单生成口味偏好矩阵
实际测试中发现,当用户数据稀疏时单独使用UserCF的准确率只有58%,而混合策略可将准确率提升至82%
3. 系统核心模块实现
3.1 用户行为采集设计
为实现精准推荐,设计了多层次数据采集方案:
| 数据类型 | 采集方式 | 存储结构 | 应用场景 |
|---|---|---|---|
| 显式反馈 | 评分/评论 | MySQL关系表 | 权重系数0.7 |
| 隐式反馈 | 浏览时长 | Redis有序集合 | 权重系数0.3 |
| 上下文数据 | GPS/时间 | MongoDB文档 | 场景化推荐 |
关键代码片段(行为日志AOP拦截):
java复制@Aspect
@Component
public class BehaviorLogAspect {
@AfterReturning("execution(* com..controller.*.*(..)) && @annotation(loggable)")
public void afterMethod(JoinPoint jp, Loggable loggable) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
UserBehaviorLog log = new UserBehaviorLog();
log.setUserId(JwtUtil.getUserId(request));
log.setBehaviorType(loggable.value());
log.setCreateTime(LocalDateTime.now());
rabbitTemplate.convertAndSend("user.behavior.queue", log);
}
}
3.2 订单流程优化实践
针对高并发下单场景,采用分布式事务解决方案:
- 库存预扣减:Redis原子操作保证库存准确
redis复制WATCH inventory:001 MULTI DECRBY inventory:001 1 EXEC - 消息最终一致性:通过RocketMQ事务消息处理支付与物流
- 补偿机制:定时任务检查超时未支付订单
实测数据对比:
- 传统方式:500并发下单成功率72%
- 优化方案:500并发下单成功率98.6%
4. 典型问题排查实录
4.1 推荐冷启动问题
现象:新用户首次访问时推荐质量差
解决方案:
- 构建菜品热度榜:综合销量、评分、收藏数
sql复制SELECT dish_id, (sales*0.6 + stars*0.3 + collects*0.1) AS heat FROM dishes ORDER BY heat DESC LIMIT 20 - 引入人口统计学推荐:根据年龄/性别匹配相似群体偏好
- 设计引导流程:新用户口味测试问卷
4.2 数据库性能瓶颈
现象:订单查询响应时间随数据量增加线性增长
优化步骤:
- 索引优化:为order_time、user_id建立联合索引
- 查询重构:将单条查询改为批量查询
- 引入Elasticsearch:实现毫秒级历史订单搜索
优化前后对比:
| 数据量 | 原方案响应时间 | 优化后响应时间 |
|---|---|---|
| 10万 | 320ms | 45ms |
| 100万 | 2100ms | 68ms |
5. 项目部署与运维
5.1 容器化部署方案
采用Docker Compose实现一键部署:
yaml复制version: '3'
services:
app:
image: openjdk:11-jre
ports:
- "8080:8080"
volumes:
- ./app.jar:/app.jar
command: java -jar /app.jar
depends_on:
- redis
- mysql
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
5.2 监控体系建设
- 基础监控:Prometheus + Grafana监控JVM指标
- 业务监控:自定义埋点统计推荐点击率
- 报警规则:设置接口响应时间>500ms自动告警
关键监控指标看板配置:
code复制avg(rate(http_server_requests_seconds_sum[1m])) by (uri) > 0.5
6. 项目扩展方向
在实际开发过程中,我发现系统还可以在以下方面进行深化:
- 实时推荐:接入Flink处理用户实时行为流
- 视觉推荐:使用CNN分析菜品图片特征
- 供应链优化:根据预测销量动态调整采购计划
一个特别实用的技巧是:在用户收藏菜品时,可以异步分析其收藏菜品的共同特征(如"80%收藏菜品含有'麻辣'标签"),据此动态调整用户口味标签,这种隐式反馈的利用使得推荐准确率又提升了约15%