漫谈 12306 架构

前几天在 QQ 群里跟 网友 讨论了一下 12306 架构 , 把 讨论的一些想法整理一下 。

 

总的来说 , 12306 的解决可以分为 2 个 流派 : 1 技术流 , 2 业务流 。

我们先来看看这篇文章  https://www.cnblogs.com/netfocus/p/5187241.html  , 这篇文章应该算 “业务流” 吧 !  不过有意思的是这篇文章的 回复 。 ^^

我们再来看看这篇文章  https://www.csdn.net/article/2015-03-03/2824091  , 这篇文章里有一幅 架构图 :  

从这个架构图里 , 我们可以把问题 分成 2 个问题来看 : 1 海量请求的分流  ,  2 数据的一致性 和 同步  。 

我前几天写过一篇博客 《Grid Virtual Server 和 网格计算》  https://www.cnblogs.com/KSongKing/p/9486434.html  , 在这篇文章里也提到了这 2 个问题 。  

实际上 , 12306 的问题也是 未来的互联网 要解决的问题 。 

在 《Grid Virtual Server 和 网格计算》 里提到 ,  分流 采用的是 Client 自主智能 的 选择 Server 节点 (多中心化) , 数据一致性 和 同步 采用 乐观 和 松耦合 的 方式 。

乐观 松耦合 可能需要 换一种 售票 和 购票 观念 。 所谓 新的 售票 观念 和 购票 观念 , 比如 预约 , 预约的方式 。 Book a Ticket 。

乐观 就是类似 乐观锁定 的 那种 方式 , 比如 在 12306 这个 场景上, 乐观 可以是 预定 , Book a Ticket 。

我们现在是 买票 , 买票 就是 看有没有 符合要求的 票 , 有就买, 如果 有人 比你先抢到 , 那你就后一个买 , 如果 被 抢完了 , 那 你就 买不到 , 只能再等 。

这种 “抢” 的 方式 会造成 大量的 访问 在 同一时间 拥挤 向 服务器 。

如果是 预定 的 方式 , 你 可以在 任何 时候 做 一个 预定 , 系统 可以 随时 受理 你的 预定 , 系统 受理 预定, 并不表示 现在就 购票成功 , 也 不表示 未来一定有票 , 但是 系统 会在 一定的时间 结算 某一批 预定, 然后 根据 票况 给予 预定 的 结果 。 

如果 符合你的 要求 有票 , 那么 系统 会 回复 消息 给你  “您 预定的票 已可购买 , 在 1 个 小时内 回复 xxx 确定购买 ” 。

那么 , 你 在 1个 小时内 回复 xxx 的话 (当然包括了 支付 钱) , 那么 就购买成功了 。

如果 没有 符合要求的票, 或者 符合要求的 票 已经 用完了(安排 给 在你之前 预定的 人们 了) , 那么 系统 会回复 你 “没有 符合您的 要求的 票” 或者 “符合要求的 票 已预定完 , 请再次 预定” 。

你 可以 再次 预定 , 然后 等待 系统通知 , 如此 循环 。

如果 从 架构 的 角度 来 解释 预定 这种 业务 , 可以 这样解释 , 传统的 购买 相当于 同步 , 预定 相当于 异步 , 预定(异步) 可以解决 同一时间 大量请求 拥挤向 服务器 的 问题 。

同时可以解决 数据 一致性 和 同步 的 问题 。

异步 可以 在 一定的时间 进行 一次 “结算” , 就不需要像 同步方式 那样 为了 数据一致性 和 数据同步 而 需要 极致 的 服务器资源 和 网络资源 。

你把 需求 提给 服务器 , 服务器 不是 即时(同步) 答复 , 而是, “先考虑一下” , 把 很多 用户 的 需求 都 汇集 一下 , 再统一答复一次 。

消息队列 是 “架构” 里 异步 的 代表 , 但在这里说的 解决方案 中, 具体的 技术 可以是 各种各样 。

轮询 Redis , 甚至 轮询 数据库 也是可以的么 。  ^^

事实上 , 用户的 需求 会先持久化 , 所以, 可能 会 轮询 数据库 。

因为 是 异步 乐观 松耦合 的 架构 , 所以 , 轮询 数据库 也是 很轻松 的 ,不会给 系统造成 负担 。

 

我们再看上面的那个 架构图 , 图的下方 列出了    余票查询集群 、 用户登录集群 、 订单分级查询 、 票价计算集群 、 实名制身份确认集群   5  项 。

我们可以看到图的中央  , 红色 粗的 箭头 “海量购票请求” , 这个就是来自于  全国 的 用户 的 购票请求。这个 请求 是 指向   “铁路总公司数据中心” 。

中央 还有一个  蓝色 的  比较细 的 箭头 , 是  “余票查询请求分流” , 指向   阿里云 公有云 数据中心 , 也就是说,  阿里云 公有云 数据中心 可以 来 分担  “余票查询”  业务 。

而 左侧 有一个  “主数据库” , 主数据库 的 数据 来自于   18 个路局    的 数据汇总 , 主数据库  同时 向    铁路总公司数据中心   和     阿里云数据中心(负责 余票查询分流) 提供数据(同步数据) 。

从 这个 图 的 架构 中 我们 可以看到 , 核心 交易  是  发生在   “铁路总公司 数据中心” , 就是说,  这是 一个  实时的,  中心化  的 数据库  支持 的 业务系统 。

同时 也可以 判定,  余票 查询  不是 实时 的 ,  是一个 参考性 的 资料 。 具体 能不能  买这个 票,  在 真正 买票(在  铁路总公司 数据中心 中 发生交易) 时  才能 知道 结果 。 而   “铁路总公司 数据中心”  这个    中心数据库 ,  它 的 承载能力 来自于  一个  分布式数据库  Gemfire 。  

 

QQ 群里有网友发了一段节选资料 :

 

也可以看这一段 :

 

可以看到, 12306 核心的 数据 承载能力 来自于  

1  中心数据库 是 一个 可扩展的 计算机集群

2  中心数据库 是 一个 内存数据库 , 而且 Gemfire 是一个 key value 数据库, 不是 关系数据库

 

架构图 左边 的 18个路局 到 主数据库 可能是 把 车况 和 票况 汇总给 铁路总公司 数据中心 吧 。

所谓 “两地三中心” , 两地 应该是指 铁路总公司 和 铁科院 吧 。 三中心 应该就是 铁路总公司数据中心 铁科院数据中心 阿里公有云数据中心 吧 。

总的来说呢 , 这种 中心化 的 设计 , 核心 的 处理能力 来自于 中心数据库 。 而 12306 是通过 Gemfire 这样一个 可以构建 集群 的 内存数据库 并且是 key value 数据库 来 做到这一点的 。

 

下面 , 这是根据我上面说的 多中心化 乐观(异步 预定) 画的架构图 :

 

posted on 2018-08-28 18:12  凯特琳  阅读(7019)  评论(0编辑  收藏  举报

导航