我们可以从“历史演进”“当前核心架构”两个维度来理解它。

12306网站技术架构
(图片来源网络,侵删)

历史演进:从“崩溃”到“坚不可摧”

12306的架构经历了几个关键阶段,每个阶段都是为了解决当时最棘手的问题。

初期阶段(约2011-2012年):单体架构 + 数据库瓶颈

  • 架构特点:典型的单体应用,所有功能(用户、订单、车票、支付)都耦合在一个巨大的Java应用中,数据库使用传统的Oracle + RAC (Real Application Clusters) 集群。
  • 核心问题
    • 数据库是最大瓶颈:所有请求最终都要查询和更新数据库,尤其是在春运期间,瞬时巨大的查询请求直接冲垮了数据库,导致系统雪崩。
    • 扩展性差:单体应用无法水平扩展,只能通过增加应用服务器数量,但核心数据库的压力无法缓解。
    • 用户体验极差:著名的“排队”和“系统繁忙”页面,就是数据库无法响应的直接体现。

第一次重大演进:引入缓存与读写分离

  • 架构特点
    • 引入缓存:在应用和数据库之间加入了Redis等内存数据库,将热点数据(如车次信息、余票信息)缓存起来,极大减轻了数据库的读压力。
    • 读写分离:将数据库拆分为一个主库(Master)和多个从库(Slave),写操作(如购票)走主库,读操作(如查余票)走从库。
  • 核心问题
    • 缓存穿透/击穿/雪崩:虽然引入了缓存,但在极端高并发下,缓存数据失效或大量请求直接绕过缓存,依然可能导致数据库崩溃。
    • 数据一致性问题:缓存和数据库的数据同步存在延迟,可能导致用户看到有余票但点击后提示“已售罄”的情况。

第二次重大演进:服务化与分布式架构

  • 架构特点:将庞大的单体应用拆分成多个独立的微服务。
    • 用户服务:负责用户注册、登录、个人信息管理。
    • 车次服务:负责车次、站点信息的发布和管理。
    • 订单服务:负责订单的创建、支付、状态变更。
    • 票务服务:负责余票查询、锁票、出票等核心业务。
    • 支付服务:对接第三方支付平台。
  • 技术选型:引入了Dubbo作为服务治理框架,用于服务间的发现、调用和负载均衡。
  • 核心优势
    • 解耦:各服务独立开发、部署和扩展,一个服务的故障不会直接导致整个系统崩溃。
    • 弹性伸缩:可以根据流量,对“票务服务”这类核心服务进行独立扩容,而其他服务则保持较小的规模。

第三次重大演进:引入云原生与消息队列

  • 架构特点:这是12306架构成熟的关键一步,全面拥抱云原生技术。
    • 消息队列:引入Kafka等消息队列,购票流程不再是同步的“下单-锁票-支付”,而是变成了异步的“下单 -> 发送消息 -> 消费消息完成锁票”。
      • 削峰填谷:将瞬时高并发请求缓冲到消息队列中,后端的票务服务按自己的处理能力消费消息,避免了流量洪峰直接冲击核心业务。
      • 系统解耦:订单服务和票务服务通过消息队列解耦,提高了系统的稳定性和容错能力。
    • 容器化与编排:全面采用Docker进行应用打包,并使用Kubernetes (K8s) 进行容器编排和自动化管理,实现了应用的快速部署、弹性伸缩和故障自愈。
    • 多级缓存:构建了从浏览器到应用再到数据库的多级缓存体系,如CDN、浏览器缓存、Nginx缓存、应用缓存、Redis缓存等,最大限度减少对数据库的访问。

当前核心架构(深度解析)

现在的12306架构是一个高度复杂、多层分级的分布式系统,我们可以将其从上到下分为几个层次:

用户接入层

这是用户访问的第一道关口,目标是高效、安全地接收海量用户请求。

  • CDN (Content Delivery Network):缓存静态资源(如JS、CSS、图片)和部分动态页面(如首页、车次列表),将内容推离用户最近的节点,加速访问,并减轻源站压力。
  • 负载均衡:通过SLB (Server Load Balancer) 或 F5 硬件设备,将海量的用户请求均匀分发到后端的多个Web服务器集群。
  • WAF (Web Application Firewall):防护SQL注入、XSS等网络攻击,保障系统安全。

应用服务层

这是业务逻辑的核心执行层,由多个独立的微服务集群组成。

12306网站技术架构
(图片来源网络,侵删)
  • 技术栈:基于Java开发,运行在Kubernetes管理的容器集群中。
  • 核心服务
    • 前端服务:负责渲染页面,调用后端API。
    • 用户服务:处理用户认证、授权、个人信息。
    • 车次服务:提供车次、席别、站点等基础数据查询。
    • 订单服务:处理订单的创建、状态流转、取消等。
    • 票务服务最核心的服务,处理余票查询、锁票、出票逻辑,为了保证高性能,这部分逻辑通常非常精简。
    • 支付服务:对接支付宝、微信支付等渠道。
  • 特点
    • 无状态设计:服务实例本身不保存用户状态,所有状态存储在外部(如Redis、数据库),方便水平扩展。
    • 弹性伸缩:K8s根据实时流量自动增减服务实例的数量,例如在开售高峰瞬间启动大量实例,售完后自动缩减。

数据存储层

这是系统的数据基石,采用了多种数据库和技术,以满足不同场景的需求。

  • 关系型数据库
    • 主库:处理写操作(如创建订单、锁票),为了保证数据强一致性和可靠性,仍然可能使用OracleMySQL集群,并配有主从复制和异地灾备方案。
    • 从库:处理读操作(如查余票、查订单),分担主库压力。
  • NoSQL数据库
    • Redis:作为核心缓存,缓存车次信息、余票信息、用户Session等,这是整个系统性能的关键。
    • MongoDB/HBase:可能用于存储非结构化或半结构化数据,如日志、用户行为分析等。
  • 分布式数据库

    对于海量的订单数据,可能会采用分布式数据库(如TiDB)进行分片存储,以突破单机数据库的性能和容量瓶颈。

  • 文件存储

    使用对象存储(如阿里云OSS)来存储用户身份证、车票图片等文件。

消息中间件层

这是系统高可用的“缓冲垫”和“解耦器”。

12306网站技术架构
(图片来源网络,侵删)
  • 核心组件KafkaRocketMQ
  • 核心作用
    • 异步处理:将“下单-锁票”这个关键流程解耦,用户下单后,订单服务只需向Kafka发送一条“订单创建”的消息,然后立即返回“下单成功”,后续的锁票、出票操作由票务服务作为消费者异步从Kafka中获取消息并执行。
    • 削峰填谷:在春运开售瞬间,会有数百万请求涌入,Kafka作为巨大的缓冲池,将这些请求暂存起来,后端的票务服务可以以稳定的速率消费,避免系统被冲垮。
    • 系统解耦与容错:如果票务服务暂时不可用,订单不会失败,消息会保留在Kafka中,待服务恢复后继续处理,保证了系统的最终一致性。

核心技术与创新点

除了上述分层架构,12306还运用了一些独特的技术来应对极端挑战。

  • 分布式事务:如何保证“下单-锁票-支付”全流程的数据一致性?12306采用了最终一致性方案,结合消息队列和本地事务,确保即使某个环节失败,数据最终也能达到一致状态。
  • 分布式锁:在并发锁票时,如何防止多个用户同时锁同一张票?使用RedisSETNX (SET if Not eXists) 命令实现分布式锁,确保锁票操作的原子性。
  • 高可用与异地多活
    • 多机房部署:核心服务在多个物理数据中心部署,当一个机房出现故障时,流量可以自动切换到其他机房。
    • 数据同步:跨机房的数据通过专线和复制技术保持同步,实现业务层面的“多活”。
  • 流量调度与风控
    • 流量整形:通过API网关对请求进行限流、熔断,防止恶意请求或异常流量。
    • 智能风控:利用大数据和机器学习技术,识别黄牛、刷票等异常行为,并进行拦截。

12306的技术架构是一个典型的“分层解耦、异步化、缓存优先、弹性伸缩”的现代化分布式系统。

  1. 从单体到微服务:实现了系统解耦和独立扩展。
  2. 从同步到异步:通过消息队列解决了高并发下的系统稳定性和性能问题。
  3. 从缓存到多级缓存:最大限度地减少了对数据库的访问,是性能提升的关键。
  4. 从物理机到云原生:通过K8s实现了极致的自动化运维和弹性伸缩能力。

12306的成功,不仅是中国工程师智慧和汗水的结晶,也为全球范围内处理超大规模高并发业务提供了宝贵的实践范例,它证明了在正确的技术架构和持续的工程优化下,即使是像春运这样看似不可能完成的任务,也能够被稳定、高效地完成。