这套影院订票系统是我在指导毕业设计过程中反复迭代的实战项目,采用SpringBoot+Vue的前后端分离架构。相比传统线下购票,系统实现了三大核心价值:
特别提示:系统设计时重点解决了影院场景特有的"座位冲突"问题,采用Redis分布式锁+数据库乐观锁双重保障,后文会详细解析实现方案。
系统采用经典的三层架构,但针对影院业务做了特殊优化:
code复制[Vue前端] ←HTTP→ [SpringBoot后端] ←JDBC→ [MySQL]
↑ ↑ ↑
ElementUI Redis缓存 MyBatis
关键设计决策:
针对开场前30分钟的购票高峰,系统实施了三重保障:
缓存策略:
java复制// Redis key设计
String key = "seat_map:" + sessionId;
// 使用Bitmap存储座位状态
redisTemplate.setBit(key, seatNumber, isOccupied);
分布式锁实现:
java复制public boolean lockSeat(Long sessionId, int seatNum) {
String lockKey = "lock:seat:" + sessionId + ":" + seatNum;
// 设置10秒过期防止死锁
return redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", Duration.ofSeconds(10));
}
数据库优化:
sql复制ALTER TABLE ticket_order
ADD INDEX idx_user_session (user_id, session_id);
时序图关键节点:
避坑指南:
java复制@Scheduled(fixedRate = 900000) // 15分钟扫描
public void releaseExpiredSeats() {
// 查询超过15分钟未支付的订单
List<Order> expiredOrders = orderMapper.selectExpiredOrders();
expiredOrders.forEach(order -> {
redisTemplate.delete("lock:seat:" + order.getSessionId());
// 更新座位状态...
});
}
采用策略模式支持多种支付方式:
java复制public interface PaymentStrategy {
PaymentResult pay(Order order);
}
@Service
@RequiredArgsConstructor
public class PaymentService {
private final Map<String, PaymentStrategy> strategies;
public PaymentResult handlePayment(Order order, String paymentType) {
PaymentStrategy strategy = strategies.get(paymentType + "Strategy");
return strategy.pay(order);
}
}
金额处理要点:
在基础表结构上,我们增加了这些优化设计:
冗余字段:
sql复制ALTER TABLE ticket_order
ADD COLUMN movie_title VARCHAR(100) COMMENT '影片名称(冗余)';
软删除设计:
sql复制ALTER TABLE movie_info
ADD COLUMN is_deleted TINYINT DEFAULT 0;
通过EXPLAIN分析发现需优化以下查询:
sql复制-- 高频查询:按分类查正在上映的影片
SELECT * FROM movie_info
WHERE genre = '动作'
AND release_date <= NOW()
ORDER BY release_date DESC;
优化方案:
sql复制CREATE INDEX idx_genre_release ON movie_info(genre, release_date);
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- redis_data:/data
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: yourpassword
volumes:
- mysql_data:/var/lib/mysql
Prometheus监控关键指标:
yaml复制# application.yml
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
application: cinema-system
重点监控:
现象:用户看到座位可选但下单时提示已售
排查步骤:
解决方案:
java复制@GetMapping("/seats/validate")
public boolean validateSeat(@RequestParam Long sessionId,
@RequestParam int seatNum) {
// 先查Redis再查数据库
}
现象:支付成功但订单状态未更新
解决方案:
java复制@Scheduled(cron = "0 */5 * * * ?")
public void checkPaymentStatus() {
// 查询支付网关获取未处理订单
}
这套系统经过3次重大版本迭代,目前已在模拟环境中支持500+并发用户同时购票。建议开发者根据实际业务需求调整以下参数: