1. 项目背景与技术选型
汽车票网上预订系统作为典型的O2O应用场景,其技术实现需要兼顾用户交互体验与业务逻辑复杂性。我们采用SpringBoot+Vue的前后端分离架构,主要基于以下考量:
后端技术栈选择依据:
- SpringBoot 2.7.x:简化配置的同时提供完整的Spring生态支持,内置Tomcat容器便于部署
- MyBatis 3.5.x:灵活处理复杂票务查询逻辑,动态SQL应对多条件筛选需求
- MySQL 8.0:事务支持完善,配合索引优化可处理高并发订票请求
前端技术决策要点:
- Vue 3.x组合式API:更好的TypeScript支持,组件复用率提升40%
- Axios拦截器:统一处理401认证和票务库存变更提示
- Vue Router路由守卫:实现购票流程的步骤验证
实战经验:在票务系统开发中,建议将座位库存信息通过Redis缓存,避免MySQL行锁竞争。我们实测QPS从200提升到1500+
2. 核心业务模块设计
2.1 票务管理模块实现
数据库表设计遵循第三范式的同时,针对高频查询做了适当冗余:
sql复制CREATE TABLE `ticket` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`schedule_id` BIGINT NOT NULL COMMENT '班次ID',
`seat_no` VARCHAR(10) NOT NULL COMMENT '座位号',
`status` TINYINT DEFAULT 0 COMMENT '0-待售 1-已售 2-锁定',
`price` DECIMAL(10,2) NOT NULL,
`start_station_id` INT NOT NULL,
`end_station_id` INT NOT NULL,
KEY `idx_schedule` (`schedule_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
并发控制方案:
- 乐观锁实现(版本号机制)
- 分布式锁(Redisson实现)
- 库存预扣减(Redis原子操作)
2.2 支付流程设计
支付状态机采用Spring StateMachine实现:
java复制@Configuration
@EnableStateMachine
public class PaymentStateMachineConfig
extends EnumStateMachineConfigurerAdapter<PaymentState, PaymentEvent> {
@Override
public void configure(StateMachineStateConfigurer<PaymentState, PaymentEvent> states)
throws Exception {
states
.withStates()
.initial(PaymentState.WAITING)
.states(EnumSet.allOf(PaymentState.class));
}
}
避坑指南:支付超时订单要配置单独的定时任务处理,避免长时间占用库存。建议超时时间设置为15分钟。
3. 前后端交互关键实现
3.1 API接口规范
采用RESTful设计原则,配合Swagger文档:
yaml复制paths:
/api/tickets:
get:
tags: [Ticket]
parameters:
- $ref: '#/components/parameters/startStationId'
- $ref: '#/components/parameters/endStationId'
responses:
200:
description: 班次列表
content:
application/json:
schema:
$ref: '#/components/schemas/TicketList'
安全措施:
- JWT令牌认证
- 敏感参数加密(如用户手机号)
- 防XSS过滤(前端vue-sanitize+后端Jackson转义)
3.2 前端工程化实践
Vue项目结构优化方案:
code复制src/
├── api/ # 接口封装
├── components/ # 公共组件
│ ├── payment/
│ │ ├── Alipay.vue
│ │ └── WechatPay.vue
├── composables/ # 组合式函数
│ └── useTicket.js
└── views/
├── booking/ # 订票流程
└── order/ # 订单管理
性能优化点:
- 路由懒加载
- 接口请求防抖处理
- 大数据列表虚拟滚动
4. 系统部署实战指南
4.1 后端部署流程
- 生产环境打包:
bash复制mvn clean package -DskipTests -Pprod
- Dockerfile配置示例:
dockerfile复制FROM openjdk:17-jdk-alpine
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- Nginx反向代理配置关键项:
nginx复制location /api/ {
proxy_pass http://backend:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 300s;
}
4.2 前端部署注意事项
- 环境变量配置:
env复制VITE_API_BASE_URL=/api
VITE_CDN_ENABLED=true
- 静态资源缓存策略:
nginx复制location / {
try_files $uri $uri/ /index.html;
expires 1y;
add_header Cache-Control "public";
}
- HTTPS配置最佳实践:
- 启用HTTP/2
- 配置HSTS头部
- OCSP装订优化
5. 典型问题排查手册
5.1 跨域问题解决方案
SpringBoot后端配置:
java复制@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
5.2 MyBatis缓存冲突
症状:查询结果不符合预期
排查步骤:
- 检查是否开启二级缓存
- 确认mapper.xml中flushCache配置
- 验证事务隔离级别
最终方案:在涉及库存操作的Mapper上添加:
xml复制<select id="selectForUpdate" flushCache="true" useCache="false">
SELECT * FROM ticket WHERE id=#{id} FOR UPDATE
</select>
6. 项目扩展方向建议
6.1 智能化升级方案
- 基于用户历史数据推荐线路
- 结合LBS的附近车站提示
- 票价动态预测模型
6.2 微服务化改造
拆分建议:
- 用户服务(独立鉴权)
- 票务服务(核心业务)
- 支付服务(第三方对接)
- 通知服务(短信/邮件)
改造关键技术点:
- Spring Cloud Gateway统一入口
- Nacos服务注册发现
- Seata分布式事务
实际部署中发现Docker Swarm对中小规模系统更友好,K8s学习曲线较陡。我们在4核8G服务器上采用Docker Compose部署,可稳定支撑3000+日订单量。特别要注意MySQL的innodb_buffer_pool_size配置,建议设置为物理内存的70%。
