1. 项目背景与核心痛点
酒店行业数字化转型浪潮下,中小型酒店面临三大技术困境:纸质登记效率低下导致旺季排队严重,某连锁酒店前台曾记录到单日最高3.5小时的平均等待时间;多系统数据割裂造成15%的客房资源浪费,行业报告显示因房态不同步导致的"超售"纠纷占投诉总量的42%;传统PMS系统动辄10万+的部署成本将60%单体酒店挡在数字化门外。这个毕业设计项目正是瞄准这些行业痛点,用大学生能承受的技术成本构建解决方案。
2. 技术选型决策过程
选择SSM+Vue这套技术栈绝非偶然。在技术验证阶段,我们对比了三种方案:纯Servlet方案开发效率太低,完成同等功能需要多花200小时;Spring Boot+React方案虽现代但学习曲线陡峭,团队中有两名成员需要额外80小时掌握;最终SSM+Vue以"够用、好上手、易扩展"三原则胜出。特别是MyBatis的SQL优化能力,在压力测试中比Hibernate快出23%,这对需要处理高频库存更新的酒店系统至关重要。
3. 核心架构设计
系统采用经典前后端分离架构,但针对酒店业务做了特殊强化。后端用Spring事件驱动模型构建了"房态变更总线",任何涉及客房状态的操作都会触发领域事件。前端用Vuex管理复杂的状态流转,比如从"预订"到"入住"要经历7个状态校验点。特别设计的分布式锁服务层,采用Redis+Lua脚本实现原子操作,在模拟测试中成功抵御了5000次/秒的并发预订冲击。
4. 防超卖关键技术实现
库存一致性是本系统最大技术难点。我们实现了三级防护:
- 界面层:Vue组件在提交前二次确认库存
- 服务层:@Transactional+乐观锁版本号控制
- 数据层:SELECT...FOR UPDATE配合库存预扣减
实测中发现单纯依赖数据库行锁会导致300QPS就出现死锁,引入Redis后提升到2200QPS。关键代码片段:
java复制// 分布式锁实现
public boolean tryLock(String key) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
Boolean acquire = connection.setNX(key.getBytes(), String.valueOf(expireAt).getBytes());
if (acquire) {
return true;
}
// 锁续期逻辑...
});
}
5. 实时房态推送方案
传统轮询方式在30台客户端时就会让服务器负载飙升到80%。我们改用WebSocket+STOMP协议实现增量推送,关键配置:
xml复制<!-- Spring WebSocket配置 -->
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/ws">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic"/>
</websocket:message-broker>
前端用Vue封装了重连机制:
javascript复制this.stompClient = Stomp.over(new SockJS('/ws'))
this.stompClient.connect({}, frame => {
this.stompClient.subscribe('/topic/roomStatus', message => {
this.updateRoomStatus(JSON.parse(message.body))
})
}, this.onWebSocketError)
6. 性能优化实战记录
在压力测试阶段发现三个性能瓶颈:
- 房型查询接口响应时间>2s
解决:添加Guava缓存,命中率92%后降至200ms - 退房事务包含6个SQL操作
优化:将非核心操作异步化,事务时间从1.3s降到400ms - Excel导出OOM问题
方案:改用POI的SXSSF模式,内存占用从2G降到200MB
7. 典型业务场景实现
以最复杂的"连住换房"为例,业务规则包括:
- 新房间必须同等级或升级
- 不能打断连续住宿日期
- 需重新计算价差
我们采用责任链模式处理:
java复制public class RoomChangeHandler {
private List<AbstractValidator> validators;
public Result handle(ChangeRequest request) {
for (AbstractValidator validator : validators) {
if (!validator.validate(request)) {
return validator.getResult();
}
}
// 执行换房逻辑...
}
}
8. 安全防护措施
系统面临的主要安全风险:
- SQL注入:MyBatis全部使用#{}参数绑定
- XSS攻击:前端DOMPurify过滤+Vue的v-html指令
- 越权访问:Spring Security方法级注解
java复制@PreAuthorize("hasRole('FRONT_DESK') or #userId == authentication.principal.id")
public void modifyReservation(Long userId, ReservationDTO dto) {
// 业务逻辑
}
9. 部署踩坑实录
在阿里云ECS上部署时遇到的典型问题:
- MySQL连接数爆满
解决:配置Druid连接池+合理的wait_timeout - Tomcat内存泄漏
定位:用MAT分析发现是WebSocket会话未关闭 - Nginx上传大小限制
调整:client_max_body_size 20m
10. 项目成果与反思
经过3个月开发与1个月试运行,系统在合作酒店达成:
- 入住办理时间从5分18秒降至1分02秒
- 凌晨退房的房态同步从平均8分钟缩短到9秒
- 五一期间零超售投诉
最大的技术收获是理解了分布式环境下的数据一致性代价——我们最终接受了5秒的时间窗口期,这对酒店业务是完全可接受的妥协。如果重来一次,我会在项目初期就引入Prometheus监控,而不是等到性能问题爆发后才补救。