1. 项目概述
这个基于SpringBoot的影院售票系统是我去年带队开发的一个实战项目,从需求分析到上线部署全程参与。系统采用B/S架构,前端使用Thymeleaf模板引擎,后端基于SpringBoot 2.7.x构建,数据库选用MySQL 8.0,实现了从影片管理、排期设置到在线选座、支付结算的全流程功能。特别在高峰时段并发控制上,我们通过Redis分布式锁+本地缓存二级方案,成功扛住了开票日的流量冲击。
2. 核心架构设计
2.1 技术栈选型考量
后端选择SpringBoot主要基于:
- 快速启动特性(内嵌Tomcat)
- 完善的生态体系(Spring Data JPA+MyBatis混合使用)
- 自动配置机制简化了Redis、RabbitMQ等中间件集成
数据库设计遵循三范式的同时做了适当反范式优化:
sql复制-- 影厅座位表采用JSON存储座位矩阵
CREATE TABLE `hall_seat` (
`hall_id` INT NOT NULL,
`seat_map` JSON DEFAULT NULL, -- 存储[[1,1,1],[1,0,1]]格式矩阵
PRIMARY KEY (`hall_id`)
) ENGINE=InnoDB;
2.2 高并发场景应对
针对秒杀式购票场景,我们实现了:
- 库存预热:放映计划创建时同步座位数据到Redis
- 分布式锁:Redisson实现的可重入锁
- 本地缓存:Caffeine缓存热点场次信息
- 异步日志:购票记录通过RabbitMQ异步落库
3. 关键功能实现
3.1 选座算法实现
核心座位推荐逻辑:
java复制public List<Seat> recommendBestSeats(Hall hall, int count) {
int[][] seats = hall.getSeatMatrix();
// 黄金区域算法:优先推荐中间偏后区域
int centerX = seats[0].length / 2;
int startRow = (int)(seats.length * 0.6);
return findConsecutiveSeats(seats, startRow, centerX, count);
}
3.2 支付模块集成
采用策略模式支持多种支付方式:
java复制public interface PaymentStrategy {
PaymentResult pay(Order order);
}
@Service
@RequiredArgsConstructor
public class PaymentService {
private final Map<String, PaymentStrategy> strategies;
public PaymentResult handlePayment(String type, Order order) {
return strategies.get(type).pay(order);
}
}
4. 部署实践
4.1 多环境配置
通过Spring Profiles实现:
yaml复制# application-prod.yml
spring:
datasource:
url: jdbc:mysql://cluster-mysql:3306/cinema?useSSL=false
hikari:
maximum-pool-size: 20
redis:
cluster:
nodes: redis-node1:6379,redis-node2:6379
4.2 性能调优
通过JMeter压测发现的优化点:
- Nginx静态资源缓存
- MyBatis二级缓存配置
- Tomcat线程池参数调整
- JVM参数优化(G1垃圾回收器)
5. 典型问题排查
5.1 座位冲突问题
现象:多个用户同时选中相同座位
解决方案:
- 采用CAS乐观锁更新座位状态
- 前端轮询检查座位状态变化
- 增加座位预留有效期(15分钟)
5.2 支付超时处理
建立补偿任务机制:
java复制@Scheduled(fixedDelay = 300000)
public void checkPendingPayments() {
List<Order> pendingOrders = orderRepo.findByStatus(OrderStatus.PAYING);
pendingOrders.forEach(order -> {
PaymentStatus status = paymentGateway.checkStatus(order.getPaymentId());
if(status == PaymentStatus.TIMEOUT) {
order.releaseSeats();
}
});
}
6. 安全防护措施
- 防SQL注入:MyBatis全部使用#{}参数绑定
- XSS防护:Jackson配置HTML转义
- CSRF防护:Spring Security默认启用
- 敏感数据加密:采用Jasypt加密数据库连接信息
这个项目让我深刻体会到,影院系统真正的挑战不在于基础CRUD实现,而在于如何平衡用户体验与系统稳定性。特别是在座位状态同步这个看似简单的功能上,我们前后迭代了3个版本才达到理想效果。建议后续开发者重点关注分布式环境下的状态一致性问题和突发流量应对方案。
