1. 项目背景与核心价值
航空票务系统作为现代民航业的核心支撑平台,其技术演进直接关系到千万旅客的出行体验。传统基于Servlet/JSP的机票管理系统普遍面临架构臃肿、响应迟缓的问题,而采用SpringBoot构建的现代化解决方案能够实现毫秒级票务查询和每秒千级订单处理能力。这个毕业设计项目正是瞄准了民航数字化转型中的三个关键痛点:多源航班数据整合、高并发订单处理、移动端友好交互。
我在实际民航IT系统开发中发现,一个合格的票务平台必须同时满足航司运营(航班调度)、代理商分销(佣金管理)、旅客服务(全流程体验)三类角色的需求。本系统通过SpringBoot+MyBatis技术栈,采用前后端分离架构,实现了从航班动态查询到电子登机牌生成的全链条服务。特别在2023年民航业复苏背景下,这类系统的稳定性和扩展性显得尤为重要。
2. 系统架构设计解析
2.1 技术选型决策矩阵
核心框架选择SpringBoot 2.7.x版本(LTS支持至2025年),相较于传统SSM架构具备三大优势:
- 内嵌Tomcat容器实现一键部署,启动时间从原来的15秒缩短到3秒内
- 自动配置机制减少70%以上的XML配置
- Actuator端点提供完善的系统监控
数据库采用MySQL 8.0+InnoDB集群方案,主要考虑:
- 航班基础数据的关系型特征(机场、航线、机型等)
- 事务处理需求(座位库存的ACID保证)
- 地理空间数据支持(机场坐标、航线距离计算)
缓存层使用Redis 6.2实现:
- 热门航线查询缓存(TTL 5分钟)
- 分布式锁控制座位抢占
- 秒杀场景的库存预扣减
2.2 微服务化拆分策略
虽然作为毕业设计可采用单体架构,但为体现现代架构思想,建议按业务域进行逻辑拆分:
java复制com.aviation
├── flight-core // 航班基础服务
├── booking-engine // 订票引擎
├── payment-gateway // 支付网关
├── itinerary-mgr // 行程管理
└── admin-console // 运营后台
每个模块通过SpringBoot Starter实现能力封装,例如订票引擎需要依赖:
xml复制<dependency>
<groupId>com.aviation</groupId>
<artifactId>flight-core-client</artifactId>
<version>1.0.0</version>
</dependency>
2.3 高并发设计要点
机票预订具有明显的瞬时高峰特征(如节假日放票时段),系统需重点考虑:
-
库存优化方案:
- 采用异步扣减+定时对账模式
- 使用Redis原子操作实现座位锁定
java复制// 座位抢占逻辑示例 Boolean locked = redisTemplate.opsForValue() .setIfAbsent("lock:flight:"+flightNo+":"+seatNo, userId, 30, TimeUnit.SECONDS); -
分布式事务处理:
- 订票流程涉及航班服务、订单服务、支付服务
- 采用Seata AT模式保证最终一致性
yaml复制seata: enabled: true application-id: booking-service tx-service-group: aviation_tx_group
3. 核心业务模块实现
3.1 航班动态管理
航班数据聚合是系统的基础能力,需要处理:
- 定期同步IATA标准数据(通过Quartz定时任务)
- 实时接入空管ADS-B信号(WebSocket长连接)
- 人工调整航班计划(Admin后台)
实体关系设计要点:
sql复制CREATE TABLE `t_flight` (
`id` BIGINT PRIMARY KEY,
`flight_no` VARCHAR(6) NOT NULL COMMENT 'CA1234',
`departure_airport` CHAR(3) NOT NULL COMMENT 'PEK',
`arrival_airport` CHAR(3) NOT NULL COMMENT 'SHA',
`departure_time` DATETIME NOT NULL,
`arrival_time` DATETIME NOT NULL,
`aircraft_id` INT COMMENT '机型',
`base_price` DECIMAL(10,2) NOT NULL,
`status` TINYINT DEFAULT 1 COMMENT '1-计划 2-起飞 3-到达',
SPATIAL INDEX(`departure_airport`, `arrival_airport`)
) ENGINE=InnoDB;
3.2 智能票价计算
机票价格动态受多种因素影响:
java复制public BigDecimal calculateFinalPrice(Flight flight, User user) {
// 基础价格
BigDecimal price = flight.getBasePrice();
// 动态因素
price = price.multiply(dynamicPricingService.getDemandFactor(flight));
// 用户等级折扣
if (user.getLevel() > 1) {
price = price.multiply(memberService.getDiscountRate(user));
}
// 税费计算
price = price.add(taxService.calculateTax(flight));
return price.setScale(2, RoundingMode.HALF_UP);
}
3.3 订单状态机设计
订单生命周期管理采用状态模式:
mermaid复制stateDiagram-v2
[*] --> PENDING
PENDING --> PAID: 支付成功
PENDING --> CANCELLED: 用户取消
PAID --> COMPLETED: 出票成功
PAID --> REFUNDING: 申请退票
REFUNDING --> REFUNDED: 退款完成
REFUNDING --> REJECTED: 退票拒绝
对应Spring状态机实现:
java复制@Configuration
@EnableStateMachineFactory
public class OrderStateMachineConfig
extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {
@Override
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states)
throws Exception {
states.withStates()
.initial(OrderState.PENDING)
.states(EnumSet.allOf(OrderState.class));
}
}
4. 关键问题解决方案
4.1 座位冲突处理
采用乐观锁+重试机制解决并发选座:
java复制@Transactional(isolation = Isolation.REPEATABLE_READ)
public BookingResult bookSeat(Long flightId, String seatNo, Long userId) {
int retry = 3;
while (retry-- > 0) {
FlightSeat seat = seatMapper.selectForUpdate(flightId, seatNo);
if (seat.getStatus() == SeatStatus.AVAILABLE) {
seat.setStatus(SeatStatus.LOCKED);
if (seatMapper.updateWithVersion(seat) > 0) {
return BookingResult.success();
}
}
Thread.sleep(100);
}
return BookingResult.failed("座位已被占用");
}
4.2 支付超时控制
使用Spring的@Scheduled实现订单自动取消:
java复制@Scheduled(fixedRate = 300000) // 每5分钟检查
public void cancelUnpaidOrders() {
List<Order> orders = orderMapper.selectExpiredOrders();
orders.forEach(order -> {
order.setState(OrderState.CANCELLED);
orderMapper.update(order);
seatService.releaseSeat(order.getFlightId(), order.getSeatNo());
});
}
4.3 行程冲突检测
用户多段行程的时间冲突校验算法:
java复制public boolean checkItineraryConflict(List<Itinerary> exists, Itinerary newOne) {
return exists.stream().anyMatch(item ->
item.getDepartureTime().isBefore(newOne.getArrivalTime()) &&
item.getArrivalTime().isAfter(newOne.getDepartureTime())
);
}
5. 系统优化实践
5.1 查询性能提升
航班搜索的Elasticsearch优化方案:
json复制{
"settings": {
"index": {
"number_of_shards": 3,
"refresh_interval": "30s"
}
},
"mappings": {
"properties": {
"departure": { "type": "keyword" },
"arrival": { "type": "keyword" },
"departure_time": { "type": "date" },
"duration": { "type": "integer" },
"price": { "type": "double" },
"aircraft": { "type": "text" }
}
}
}
5.2 前端体验优化
基于Vue3的机票日历组件关键实现:
vue复制<template>
<div class="calendar">
<div
v-for="day in days"
:key="day.date"
@click="selectDay(day)"
:class="{ 'has-flight': day.flights.length }">
{{ day.date }}
<span v-if="day.lowestPrice">{{ day.lowestPrice }}</span>
</div>
</div>
</template>
<script setup>
const props = defineProps({
flights: Array
});
const days = computed(() => {
// 生成当月日历并匹配航班数据
});
</script>
6. 部署与监控方案
6.1 容器化部署
Docker Compose编排示例:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:6.2-alpine
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
volumes:
mysql_data:
6.2 监控指标配置
SpringBoot Actuator关键端点:
properties复制management.endpoints.web.exposure.include=health,metrics,prometheus
management.metrics.export.prometheus.enabled=true
management.endpoint.health.show-details=always
Grafana监控看板应包含:
- JVM内存/线程指标
- 接口QPS/RT统计
- 数据库连接池使用率
- Redis命中率监控
7. 毕业设计扩展建议
-
人工智能应用方向:
- 基于历史数据的机票价格预测模型
- 用户画像的个性化推荐算法
-
移动端增强:
- 微信小程序端开发
- 电子登机牌OCR识别功能
-
行业特色功能:
- 航班延误智能补偿计算
- 联程机票自动规划算法
项目开发中常见问题处理:
- 航班时间显示混乱 → 务必统一使用UTC时间存储,前端按用户时区转换
- 价格计算精度丢失 → 使用BigDecimal处理货币运算
- 高并发测试时数据库连接耗尽 → 合理设置连接池大小(建议公式:connections = (core_count * 2) + effective_spindle_count)