1. 项目背景与核心需求
酒店点餐系统作为现代餐饮服务数字化转型的关键环节,正在从传统纸质菜单向智能化服务转型。这个基于Spring Boot的毕业设计项目,瞄准了中小型酒店餐饮部门的实际运营痛点。我去年参与过本地一家商务酒店的系统升级,亲眼目睹服务员手写点单导致的错单、漏单问题——高峰期近30%的订单需要二次确认,平均每桌结账时间长达12分钟。
系统需要实现三个核心能力:
- 多终端实时同步:服务员手持Pad、前台电脑和厨房显示屏必须保持数据一致性,新订单到达后厨房应在3秒内收到提示
- 智能库存联动:当某菜品原料库存低于安全阈值时(如牛排剩余5份),系统自动在点餐界面标注"即将售罄"
- 数据可视化看板:经理端需要实时展示翻台率、菜品畅销榜、平均用餐时长等12项关键指标
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 Spring Boot选型考量
选择Spring Boot 2.7.18版本(非最新的3.x系列)主要基于:
- 与JDK8的兼容性:酒店现有服务器多为CentOS 7系统,仅支持JDK8
- 组件成熟度:MyBatis-Plus 3.5.3在事务管理上的稳定性经过验证
- 启动速度:实测在2G内存的测试机上,冷启动仅需4.2秒
java复制// 典型的多数据源配置示例
@Configuration
@MapperScan(basePackages = "com.hotel.menu.mapper", sqlSessionTemplateRef = "menuSqlSessionTemplate")
public class MenuDataSourceConfig {
@Bean(name = "menuDataSource")
@ConfigurationProperties(prefix = "spring.datasource.menu")
public DataSource menuDataSource() {
return DataSourceBuilder.create().build();
}
}
2.2 前后端分离实践
采用Vue3+Element Plus前端架构时,遇到跨域问题的解决方案:
- 开发阶段:配置Spring Boot的CorsFilter
- 生产环境:使用Nginx反向代理,添加以下配置:
nginx复制location /api/ {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
add_header 'Access-Control-Allow-Origin' '$http_origin';
}
3. 核心业务实现
3.1 实时订单推送方案
对比了三种方案后选择WebSocket:
- 轮询:每5秒请求一次,测试时发现CPU占用率达65%
- SSE:安卓端兼容性问题导致20%的设备接收失败
- WebSocket:最终实现方案,关键代码如下:
java复制@ServerEndpoint("/orderPush/{staffId}")
@Component
public class OrderWebSocket {
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("staffId") String staffId) {
sessionMap.put(staffId, session);
}
}
3.2 库存预警设计
采用Redis的原子计数器实现实时库存扣减:
java复制public boolean deductStock(Long dishId, int quantity) {
String key = "stock:" + dishId;
long remain = redisTemplate.opsForValue().decrement(key, quantity);
if(remain < 0) {
// 库存不足时回滚
redisTemplate.opsForValue().increment(key, quantity);
return false;
}
if(remain < WARNING_THRESHOLD) {
pushWarningMessage(dishId);
}
return true;
}
4. 性能优化实战
4.1 数据库分表策略
订单表按月份分表(order_202307),使用MyBatis拦截器自动路由:
java复制@Intercepts({
@Signature(type= StatementHandler.class, method="prepare", args={Connection.class, Integer.class})
})
public class TableSplitInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) {
String sql = boundSql.getSql();
if(sql.contains("order")) {
String newSql = sql.replace("order", "order_" + DateUtil.format(new Date(), "yyyyMM"));
resetSql(invocation, newSql);
}
return invocation.proceed();
}
}
4.2 缓存雪崩防护
采用三级缓存策略:
- 本地Caffeine缓存(有效期5分钟+随机30秒)
- Redis集群缓存(有效期30分钟)
- 数据库查询添加Hystrix熔断
实测在200并发请求下,系统响应时间从3.2秒降至480毫秒。
5. 部署与监控
5.1 Docker Compose编排
关键服务包括:
yaml复制services:
app:
image: hotel-menu:1.0
ports:
- "8080:8080"
depends_on:
- redis
- mysql
redis:
image: redis:6-alpine
volumes:
- redis_data:/data
5.2 Prometheus监控配置
在application.yml中添加:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
配置Grafana看板监控JVM内存、订单吞吐量等15项指标。
6. 典型问题解决方案
6.1 微信支付回调处理
遇到的坑:微信支付要求响应必须在3秒内完成,但我们的订单处理平均需要4.5秒。最终方案:
- 接收到回调后立即返回success
- 将实际处理逻辑放入RabbitMQ延迟队列
- 补偿机制:每小时扫描未处理完成的订单
6.2 高并发下的订单重复
使用Redis分布式锁解决:
java复制public boolean tryLock(String lockKey, long expireSeconds) {
return redisTemplate.opsForValue().setIfAbsent(
lockKey,
"1",
expireSeconds,
TimeUnit.SECONDS
);
}
7. 源码结构说明
项目采用多模块设计:
code复制hotel-menu-parent
├── menu-common // 通用工具类
├── menu-dao // 数据访问层
├── menu-service // 业务逻辑
├── menu-web // 控制器层
└── menu-admin // 管理后台
重点推荐查看:
MenuServiceImpl.java中的@Transactional嵌套事务处理DynamicDataSourceConfig.java实现的多租户数据隔离ScheduledTasks.java里的分布式定时任务锁
8. 扩展建议
-
可增加的功能:
- 人脸识别会员系统(基于OpenCV)
- 智能推荐算法(协同过滤+热销榜)
- 语音点餐接入(阿里云语音识别API)
-
性能压测数据:
- 4核8G服务器可支撑:
- 800TPS的订单创建
- 1200并发的菜单查询
- 500MB/day的日志量
- 4核8G服务器可支撑:
-
我在开发中最大的收获:
- 永远为数据库字段预留扩展空间(如varchar长度加倍)
- 支付相关功能必须做沙箱环境全流程测试
- 复杂的业务逻辑要画状态机图再编码
