拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

南方航空双中台架构解析:业务中台与数据中台落地实践

南方航空双中台架构解析:业务中台与数据中台落地实践

简介:这份《中国南方航空数字化和双中台方案》PDF面向航空业信息化从业者、企业数字化转型负责人及中台架构学习者,系统梳理了南航在数字化管办体系、创新体系与流程管理体系上的落地经验,并重点拆解业务中台与数据中台的建设思路,可帮助读者理解大型航企如何借助平台化手段沉淀与复用企业级能力。资源包共1个PDF文件,约1.74MB,内容以图文并茂的汇报材料形式呈现,涵盖航班中心全流程管理、实时航班动态微服务、飞行员一体化分析及报表快速响应等典型场景。目前已有259人学习下载。读者可从中获取管办分离的组织设计、双中台架构的模块划分、航班全生命周期数据整合方法,以及数据驱动训练与运行决策的实践案例,适合作为数字化转型方案设计与中台落地的参考范本。

1. 南方航空数字化与双中台:一份 PDF 背后到底在解决什么问题

航司这类企业的数字化,难点从来不在“有没有系统”,而在“系统太多、数据太散、业务变化太快”。南方航空数字化和双中台方案.pdf 这个标题,指向的正是大型航司在数字化转型中绕不开的一道坎:前端业务要快速响应市场,后端系统却各自为政,订票、值机、会员、航班运行、机务、货运各有一套逻辑,数据口径不一致,新业务上线动辄要跨七八个系统做集成。双中台方案的核心思路,是把共性的业务能力和数据能力下沉,抽成可复用的“业务中台”和“数据中台”,让前台轻量化、敏捷化。这套方案适合正在做中台选型的技术负责人、数据平台工程师,以及需要理解航司数字化落地路径的架构师。它不解决“要不要上云”这种战略问题,而是回答一个更具体的工程问题:当业务系统数量超过三位数时,怎么让新业务上线从三个月缩到两周。

2. 双中台在航司场景下的架构拆解:业务中台和数据中台各管什么

2.1 业务中台:把重复的“订票-改签-退票”逻辑收成共享服务

航司的业务中台不是万能筐,它只收那些被三个以上前台系统调用的能力。以南航场景为例,最典型的共享业务能力包括:旅客身份识别、订单状态机、运价计算、库存扣减、支付路由、通知推送。这些能力如果每个渠道各写一套,光是退票规则变更就要改六处代码。业务中台的做法是,把这些能力封装成领域服务,通过 API 网关暴露,前台渠道只负责交互和展示。

具体落地时,我一般会按下面这个顺序推进。第一步,梳理现有系统的能力调用关系,找出调用频次最高的 20 个接口。第二步,判断哪些接口的业务逻辑在多个系统中重复实现。第三步,把重复逻辑抽成中台服务,原系统改为调用中台。第四步,建立 API 版本管理机制,避免中台服务变更导致前台批量故障。

# 用 API 网关日志统计高频调用接口,找出中台候选 # 假设网关日志格式为 JSON,包含 path、method、caller 字段 cat gateway_access.log | \ jq -r '[.path, .method, .caller] | @tsv' | \ sort | uniq -c | sort -rn | head -30

这段命令的作用是从网关日志里提取调用频次最高的 30 个接口。jq负责解析 JSON 日志,sort | uniq -c做计数聚合,sort -rn按次数倒序排列。参数上,head -30可以根据系统规模调整,系统越多,候选接口越多,建议先看前 50 个。拿到结果后,重点看那些被三个以上不同caller调用的接口,它们就是业务中台的首批收编对象。

注意:不要一上来就把所有接口都往中台塞。中台服务越多,治理成本越高。我见过一个项目把 200 多个接口全收进中台,结果中台团队变成瓶颈,前台改一个字段要排期两周,完全背离了敏捷的初衷。

2.2 数据中台:从“报表堆叠”到“指标口径统一”

数据中台要解决的核心问题不是“有没有数据”,而是“同一个指标在不同报表里数值不一样”。航司场景下,典型的指标冲突包括:客座率、座公里收入、常旅客活跃度、航班正常率。这些指标在营销、运行、财务三个口径下往往各算各的。数据中台的做法是,建立统一的指标定义层,把指标的计算逻辑、数据来源、更新频率固化下来,上层应用只能引用,不能自行修改。

落地路径通常分四步。第一步,盘点现有报表和指标,建立指标字典。第二步,为每个指标指定唯一的数据源和计算口径。第三步,用调度系统按统一频率计算指标,写入指标存储。第四步,提供指标查询 API,替代原来的直连数据库取数。

-- 指标字典表结构示例:统一管理指标口径 CREATE TABLE metric_dict ( metric_code VARCHAR(64) PRIMARY KEY, -- 指标编码,如 load_factor metric_name VARCHAR(128) NOT NULL, -- 指标名称,如 客座率 domain VARCHAR(32) NOT NULL, -- 所属域:营销/运行/财务 source_table VARCHAR(256) NOT NULL, -- 数据来源表 calc_logic TEXT NOT NULL, -- 计算逻辑描述 update_freq VARCHAR(16) NOT NULL, -- 更新频率:日/小时/实时 owner VARCHAR(64) NOT NULL, -- 指标负责人 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 插入客座率指标定义 INSERT INTO metric_dict (metric_code, metric_name, domain, source_table, calc_logic, update_freq, owner) VALUES ('load_factor', '客座率', '营销', 'dwd_flight_segment', 'SUM(passenger_count)/SUM(seat_capacity)', '日', '营销数据组');

这张表的关键字段是calc_logic和owner。calc_logic用文本描述计算逻辑,虽然不能直接执行,但它是口径对齐的依据。owner字段确保每个指标有人负责,避免出现“三不管指标”。update_freq决定调度频率,日频指标可以凌晨跑批,实时指标需要接流式计算。实际项目中,指标字典表往往还会加status字段做上下线管理,加version字段做口径变更追溯。

2.3 双中台的协同关系:业务中台产生数据,数据中台反哺业务

业务中台和数据中台不是两个独立项目,它们之间有明确的数据流向。业务中台在处理订票、改签等交易时,会产生大量业务事件,这些事件通过消息队列同步到数据中台,成为指标计算的原始数据。反过来,数据中台算出的旅客画像、航班热度、渠道偏好等结果,又通过 API 回传给业务中台,用于个性化推荐和动态定价。

这个协同关系落地时,最容易出问题的是数据延迟和口径不一致。业务中台的事件发出后,数据中台如果半小时后才更新指标,前台看到的推荐就是过期的。我的经验是,对时效性要求高的场景,比如登机口升舱推荐,走实时链路;对时效性要求低的场景,比如月度会员活跃度报表,走离线链路。两条链路共用同一套指标定义,但计算引擎不同。

3. 从 PDF 方案到可运行环境:双中台最小验证环境的搭建步骤

3.1 用 Docker Compose 拉起中台依赖组件

在正式投入之前,建议先用最小环境验证双中台的核心链路是否跑得通。这个环境不需要航司真实数据,用模拟数据即可。核心组件包括:API 网关、消息队列、指标计算引擎、指标存储、一个模拟前台应用。

# docker-compose.yml:双中台最小验证环境 version: '3.8' services: # API 网关:业务中台统一入口 gateway: image: nginx:1.25-alpine ports: - "8080:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro # 消息队列:业务事件同步到数据中台 kafka: image: bitnami/kafka:3.6 ports: - "9092:9092" environment: - KAFKA_CFG_NODE_ID=0 - KAFKA_CFG_PROCESS_ROLES=controller,broker - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093 - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER # 指标存储:用 PostgreSQL 模拟,生产环境可换 ClickHouse metrics-db: image: postgres:16-alpine ports: - "5432:5432" environment: - POSTGRES_DB=metrics - POSTGRES_USER=metrics_user - POSTGRES_PASSWORD=metrics_pass # 模拟前台应用:调用业务中台接口 frontend-app: build: ./frontend-app ports: - "3000:3000" depends_on: - gateway - kafka

这份 Compose 文件定义了四个服务。gateway用 Nginx 做反向代理,模拟业务中台的 API 入口。kafka用 KRaft 模式启动,不需要 ZooKeeper,适合本地验证。metrics-db用 PostgreSQL 模拟指标存储,生产环境如果指标量大、查询复杂,建议换 ClickHouse 或 Doris。frontend-app是一个简单的 Node.js 应用,模拟前台调用中台接口。启动命令是docker compose up -d,启动后用docker compose ps检查各容器状态。

注意:Kafka 的KAFKA_CFG_LISTENERS配置里,PLAINTEXT://:9092是给外部客户端连接的,CONTROLLER://:9093是内部控制器通信用的。如果本地 9092 端口被占用,改成其他端口时,frontend-app里的连接配置也要同步改。

3.2 业务中台接口的模拟与调用验证

环境起来之后,先验证业务中台的接口是否可用。下面是一个用 Python 写的模拟调用脚本,它向网关发送订票请求,然后从 Kafka 消费业务事件,确认事件已经产生。

# simulate_booking.py:模拟前台调用业务中台并验证事件产生 import requests import json from kafka import KafkaConsumer import threading # 业务中台订票接口地址(通过网关) BOOKING_API = "http://localhost:8080/api/booking/create" # 模拟订票请求 booking_payload = { "passenger_id": "P123456", "flight_no": "CZ3101", "seat_class": "Y", "amount": 1280.00, "channel": "app" } def create_booking(): """调用业务中台创建订单""" resp = requests.post(BOOKING_API, json=booking_payload, timeout=5) print(f"订票接口返回状态码: {resp.status_code}") print(f"返回内容: {resp.text}") return resp.status_code == 200 def consume_events(): """从 Kafka 消费业务事件,验证数据中台链路""" consumer = KafkaConsumer( 'booking-events', # 业务事件主题 bootstrap_servers='localhost:9092', auto_offset_reset='latest', value_deserializer=lambda m: json.loads(m.decode('utf-8')) ) print("等待业务事件...") for msg in consumer: print(f"收到事件: {msg.value}") break # 验证一条即可退出 if __name__ == "__main__": # 先启动消费者线程,再发请求 t = threading.Thread(target=consume_events, daemon=True) t.start() create_booking() t.join(timeout=10)

这个脚本做了两件事:一是通过 HTTP 调用业务中台的订票接口,二是从 Kafka 的booking-events主题消费事件。关键参数是bootstrap_servers='localhost:9092',如果 Kafka 跑在 Docker 里且端口映射不同,这里要改。auto_offset_reset='latest'表示只消费最新事件,避免读到历史数据干扰验证。实际运行时,如果订票接口返回 200 但 Kafka 没有事件,说明业务中台的事件发布逻辑没接上,需要检查中台服务里的消息生产者配置。

3.3 数据中台指标计算的调度配置

业务事件产生后,数据中台需要按调度频率计算指标。下面是一个用 Python 写的简易调度脚本,模拟日频指标的计算过程。生产环境一般用 DolphinScheduler 或 Airflow,但验证阶段用脚本更直观。

# metric_scheduler.py:模拟数据中台指标计算调度 import psycopg2 from datetime import datetime, timedelta # 指标存储连接配置 DB_CONFIG = { "host": "localhost", "port": 5432, "dbname": "metrics", "user": "metrics_user", "password": "metrics_pass" } def calc_load_factor(target_date): """计算指定日期的客座率指标""" conn = psycopg2.connect(**DB_CONFIG) cur = conn.cursor() # 从业务事件表聚合计算客座率 # 实际项目中,这里会从数据中台的明细层读取 calc_sql = """ INSERT INTO metric_value (metric_code, metric_date, metric_value, updated_at) SELECT 'load_factor', %s, CASE WHEN SUM(seat_capacity) > 0 THEN ROUND(SUM(passenger_count)::numeric / SUM(seat_capacity), 4) ELSE 0 END, NOW() ON CONFLICT (metric_code, metric_date) DO UPDATE SET metric_value = EXCLUDED.metric_value, updated_at = EXCLUDED.updated_at; """ cur.execute(calc_sql, (target_date,)) conn.commit() print(f"客座率指标计算完成: {target_date}") cur.close() conn.close() if __name__ == "__main__": # 计算前一天的客座率 yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") calc_load_factor(yesterday)

这段代码的核心是INSERT ... ON CONFLICT DO UPDATE,它保证同一天多次计算不会产生重复记录,而是覆盖更新。metric_value表需要提前建好,包含metric_code、metric_date、metric_value、updated_at四个字段,并在(metric_code, metric_date)上建唯一索引。调度频率方面,日频指标一般凌晨 2 点跑,依赖前一天的业务数据全部落库。如果业务事件有延迟,比如跨天航班,需要把调度时间往后推,或者加一个数据就绪检查。

4. 双中台落地避坑:五个让项目翻车的真实原因

4.1 中台服务粒度太细,前台调用链变成“蜘蛛网”

现象:前台一个下单请求,要依次调用用户中心、库存中心、运价中心、支付中心、通知中心五个中台服务,任何一个超时都导致下单失败。原因:中台服务拆分过细,没有做服务聚合。解决:在网关层做聚合接口,把多个中台服务组合成一个粗粒度接口暴露给前台。聚合逻辑放在 BFF(Backend for Frontend)层,而不是中台服务内部。

4.2 指标口径变更没有版本管理,历史报表全部对不上

现象:营销部门调整了“活跃会员”的定义,从“30 天内有交易”改成“30 天内有登录或交易”,结果历史报表数据全部变化,财务部门不认。原因:指标计算逻辑直接改 SQL,没有保留旧版本。解决:指标字典表加version字段,每次口径变更新增一条记录,旧版本标记为deprecated。报表查询时指定版本号,历史数据用旧版本,新数据用新版本。

4.3 业务事件丢失导致数据中台指标偏低

现象:数据中台算出的客座率比业务系统报表低 3 个百分点。原因:业务中台发事件到 Kafka 时,没有做发送确认,网络抖动时事件丢失。解决:生产者配置acks=all,并开启重试。同时在业务中台侧加本地事件表,定时对账,发现丢失的事件补发。

4.4 中台团队和前台团队职责不清,需求互相推诿

现象:前台提了一个中台接口变更需求,中台团队说“这是前台业务逻辑,不该中台改”,前台说“接口是中台的,当然中台改”。原因:没有明确中台服务的边界和变更流程。解决:建立 API 变更评审机制,明确哪些变更属于中台职责(如通用逻辑优化),哪些属于前台职责(如渠道特定逻辑)。中台只收编被多个前台复用的能力,单一渠道的特殊需求不进中台。

4.5 验证环境用真实数据,合规风险高

现象:为了验证指标计算准确性,直接把生产数据导入验证环境,被安全部门通报。原因:验证环境没有数据脱敏。解决:验证环境用模拟数据或脱敏数据。如果必须用真实数据结构,只保留字段名和类型,数值全部替换为随机值。航司数据涉及旅客隐私,脱敏不是可选项,是必选项。

5. 双中台值不值得做:一个判断标准和三个验证技巧

判断双中台值不值得做,我的标准很简单:看前台业务上线的平均周期。如果新业务上线需要跨三个以上系统做集成,且集成工作量超过开发工作量的一半,那中台就有价值。如果业务系统本来就少,或者业务变化不快,强行上中台只会增加一层调用,反而拖慢速度。

验证技巧一:用“接口复用率”衡量业务中台效果。统计中台接口被多少个前台系统调用,如果平均每个接口被三个以上前台调用,说明收编合理。如果大部分接口只有一个调用方,说明收编过度。

验证技巧二:用“指标一致率”衡量数据中台效果。随机抽取 20 个核心指标,对比中台计算结果和原系统报表结果,一致率低于 95% 就说明口径对齐没做好。

验证技巧三:用“故障隔离度”衡量双中台稳定性。模拟一个中台服务宕机,看影响范围是单个前台还是全部前台。如果全部前台都挂,说明中台成了单点,需要做降级预案。

# check_reuse_rate.py:统计中台接口复用率 import requests from collections import defaultdict # 假设网关提供接口调用关系查询 API API_RELATION_URL = "http://localhost:8080/api/gateway/relations" def check_reuse_rate(): resp = requests.get(API_RELATION_URL, timeout=5) relations = resp.json() # [{"path": "/api/user", "caller": "app"}, ...] # 统计每个接口被多少个不同 caller 调用 path_callers = defaultdict(set) for rel in relations: path_callers[rel["path"]].add(rel["caller"]) # 计算复用率 total = len(path_callers) reused = sum(1 for callers in path_callers.values() if len(callers) >= 3) rate = reused / total if total > 0 else 0 print(f"接口总数: {total}") print(f"被三个以上前台调用的接口数: {reused}") print(f"复用率: {rate:.2%}") # 列出复用率低的接口,供收编评审参考 for path, callers in path_callers.items(): if len(callers) < 3: print(f"低复用接口: {path}, 调用方: {callers}") if __name__ == "__main__": check_reuse_rate()

这个脚本从网关的调用关系 API 拉取数据,统计每个接口的调用方数量。复用率低于 60% 时,说明中台收编了太多低频接口,需要重新评审。path_callers用defaultdict(set)是为了去重,同一个调用方多次调用只算一次。实际项目中,这个统计应该每周跑一次,作为中台服务治理的常规指标。

我自己踩过最深的坑,是早期把中台当成“技术项目”来做,忽略了组织配套。中台团队和前台团队如果还是各背各的 KPI,中台只关心接口稳定性,前台只关心上线速度,两边一定打架。后来我们调整了考核方式,中台团队的绩效和前台业务上线周期挂钩,前台团队的绩效里也包含中台接口复用率,两边才真正坐到一条船上。技术方案再漂亮,组织没对齐,落地就是一场消耗战。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表