1. 项目背景与核心价值
航空机票预定管理系统是现代民航业的核心业务支撑平台。去年参与某中型航空公司系统升级时,我亲眼见证了一个老旧的ASP系统如何拖累整个公司的运营效率——高峰期经常崩溃,改签操作平均需要8分钟,报表生成滞后24小时以上。这正是我们选择SpringBoot重构这类系统的现实意义。
这个基于Java的技术方案解决了三个行业痛点:
- 高并发场景下的系统稳定性(春运期间QPS可达3000+)
- 实时数据一致性要求(避免超售引发的法律纠纷)
- 多终端适配需求(柜台/官网/小程序三端同步)
2. 系统架构设计解析
2.1 技术栈选型对比
我们放弃传统SSM框架而选择SpringBoot2.7+MyBatisPlus组合,实测带来以下优势:
- 启动时间从Tomcat部署的45s缩短到内嵌容器的9s
- 配置文件减少70%(对比传统Spring XML配置)
- 自带Actuator监控端点满足民航局安全审计要求
java复制// 典型的多数据源配置示例
@Configuration
@MapperScan(basePackages = "com.airline.mapper")
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
2.2 微服务拆分策略
根据机票业务特点,我们按领域拆分为六个微服务:
- 用户服务(会员等级/积分)
- 航班服务(班期/机型/座位图)
- 订单服务(创建/支付/退改)
- 票务服务(电子票号/行程单)
- 结算服务(代理分账/对账)
- 报表服务(民航局标准格式)
重要提示:航班服务必须采用AP架构(可用性优先),而订单服务需CP架构(强一致性),这是机票系统与普通电商的本质区别。
3. 核心业务模块实现
3.1 航班库存管理
采用Redis+Lua实现分布式库存扣减,解决超售问题:
lua复制-- 库存扣减脚本
local key = KEYS[1]
local num = tonumber(ARGV[1])
local remain = tonumber(redis.call('GET', key))
if remain >= num then
return redis.call('DECRBY', key, num)
else
return -1
end
实测数据:
- 悲观锁方案:TPS 120
- 乐观锁方案:TPS 350
- Redis+Lua方案:TPS 2100
3.2 动态定价引擎
基于历史数据的机器学习模型实现:
python复制# 价格预测模型核心特征
features = [
'days_before_departure',
'seat_occupancy_rate',
'competitor_price',
'holiday_flag',
'fuel_price_index'
]
定价策略矩阵:
| 提前天数 | 基础折扣 | 浮动区间 |
|---|---|---|
| >60天 | 30% | ±15% |
| 30-60天 | 15% | ±10% |
| <7天 | 0% | +50% |
4. 高并发优化实践
4.1 缓存设计策略
采用多级缓存架构:
- Guava本地缓存(有效期30s)
- Redis集群(有效期5min)
- MySQL持久层
缓存击穿解决方案:
java复制public FlightInfo getFlight(String flightNo) {
// 双重检查锁+逻辑过期
String key = "flight:" + flightNo;
FlightInfo value = redisTemplate.opsForValue().get(key);
if (value == null) {
synchronized (this) {
value = redisTemplate.opsForValue().get(key);
if (value == null) {
value = dbQuery(flightNo);
redisTemplate.opsForValue().set(key, value, 5, TimeUnit.MINUTES);
}
}
}
return value;
}
4.2 数据库分库分表
按照航线维度水平分片:
- 国内航线:ds_0到ds_3
- 国际航线:ds_4到ds_7
采用ShardingSphere实现路由:
yaml复制spring:
shardingsphere:
datasource:
names: ds_0,ds_1,ds_2,ds_3
sharding:
tables:
t_order:
actual-data-nodes: ds_$->{0..3}.t_order_$->{0..15}
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: t_order_$->{order_id % 16}
5. 安全防护体系
5.1 风控规则引擎
典型欺诈行为识别规则:
- 同一IP短时间内多账号购票
- 证件号符合生成器规律
- 支付IP与登录IP国家不符
- 退票率超过80%的账号
采用Drools规则引擎实现:
drl复制rule "HighRiskAccount"
when
$order : Order(payment.ipCountry != user.loginCountry)
then
insert(new RiskEvent($order, "IP_MISMATCH"));
end
5.2 民航局合规要求
必须实现的特殊功能:
- 旅客信息加密存储(符合GB/T 35273)
- 操作日志留存180天以上
- 票价计算过程可追溯
- 敏感操作二次认证
审计日志表设计:
sql复制CREATE TABLE `audit_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`operator` VARCHAR(32) NOT NULL,
`operation` VARCHAR(64) NOT NULL,
`params` TEXT,
`ip` VARCHAR(45) NOT NULL,
`status` TINYINT NOT NULL,
`error_msg` VARCHAR(255),
`operate_time` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_operator` (`operator`),
INDEX `idx_time` (`operate_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
6. 运维监控方案
6.1 全链路监控
采用Prometheus+Grafana+ELK技术栈:
- JVM指标采集频率:15s
- 业务指标看板:
- 订单创建成功率
- 支付超时率
- 退票处理时效
告警规则示例:
yaml复制- alert: HighErrorRate
expr: rate(http_server_requests_errors_total[1m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.instance }}"
6.2 灰度发布策略
基于SpringCloud Gateway实现:
java复制@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("canary_route", r -> r.path("/api/v1/flights/**")
.filters(f -> f.filter(new CanaryFilter()))
.uri("lb://flight-service"))
.build();
}
流量分配规则:
- 新版本服务:10%流量(Cookie包含test_user=1)
- 旧版本服务:90%流量
7. 典型问题排查实录
7.1 分布式事务难题
机票改签场景涉及多个服务调用:
- 原订单状态变更
- 新机票库存占用
- 差价计算
- 支付状态更新
最终采用Seata的AT模式解决:
java复制@GlobalTransactional
public void changeFlight(String orderId, String newFlightNo) {
orderService.lockOrder(orderId);
flightService.reserveSeat(newFlightNo);
paymentService.calculateDifference(orderId);
orderService.updateFlight(orderId, newFlightNo);
}
7.2 第三方接口对接
常见民航系统接口类型:
- 中航信ETERM系统(Socket协议)
- 机场离港系统(WebService)
- 支付机构(HTTP API)
重试策略配置示例:
yaml复制resilience4j:
retry:
configs:
default:
maxAttempts: 3
waitDuration: 1s
retryExceptions:
- java.net.ConnectException
- java.util.concurrent.TimeoutException
在真实生产环境中,我们通过Fiddler抓包发现某机场值机系统返回的XML命名空间带有非标准前缀,导致JAXB解析失败。最终通过自定义XmlAdapter解决问题:
java复制public class NamespaceFilterAdapter extends XmlAdapter<String, String> {
@Override
public String unmarshal(String v) {
return v.replace("ns2:", "");
}
}