社区编辑申请
注册/登录
过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?
开发 架构 服务器运维
车票售卖特点,有一张车票卖出去就会影响到整个列车线的票数:北京开往广州的一趟列车有人买了石家庄到郑州的票,同时意味着出发点在北京-石家庄,目的地是郑州-广州的所有情况都会少一张票。

 车票售卖特点,有一张车票卖出去就会影响到整个列车线的票数:北京开往广州的一趟列车有人买了石家庄到郑州的票,同时意味着出发点在北京-石家庄,目的地是郑州-广州的所有情况都会少一张票。

1.最low的方法。每次查询车票时候都算一遍各个站点的票数,取最小值。假设一共3站,北京,石家庄,广州,共10个座位。有人要查询北京-广州的票:已经卖出了北京-石家庄9张票,石家庄-广州1张票,取中间车站的最小值10-9=1,剩一张。这样如果是20站查看两头车站的余票就要计算19次再找最小值。

为什么说它low呢?因为票数不多但是查看余票的人太多!而且人都不傻,在没票时候还会刷新!所以来一次访问计算20次,10万人加上每个黄牛开10台电脑用来刷票,瞬间访问数达到100W,想要1秒内都得到响应需要1秒计算2000W次。

2.稍微好一点的方法。票被买走时候把每个车站余票计算一下,查看余票时候直接返回这个结果。同样每秒100W访问,但是只有1000人在这秒买到了票,计算余票时候只需要1000*20=20W次,省下了1800W次的运算。

3.更“实际”一点的方法。每隔1秒同步一次数据状态。假设12306每次查余票需要更新1k数据,一般单个网卡1G带宽,理论能同时支持12.8W的访问量,100W人都要看就至少有8个服务器在工作,方法2中,余票需要存放8份的话就需要1000*8=8000次更新。还要考虑各个地区访问的不均等性,电信,网通,铁通等线路,整体列车余票情况数据量也有几十K,所以1秒8000次更新也几百兆的流量了。但是如果每隔1秒同步当前的数据状态就好很多,这样编程了1*8=8次,更新数据库传输总量1M/s左右,差不多吧?

即便如此,还是扛不住访问量。

因为电脑上12306是用的网页模式,查询车票那个页面大小6K,即便是用了ajax,刷新一次北京-郑州,这样的大站需要传输7K的纯json数据,个人感觉有很多字段都浪费了,没什么用。

 

所以就我看来,12306可以做以下改进,不是一切问题都要用技术解决的。

1.已经做了,分段放票,减少扎堆

2.12306自制一款好的抢票软件。既然抢票权在自己手里了,刷票软件就少了,大量减少流量。

3.别搞现在的图片验证码了,这些验证码刷不出来,辨识度低根本是暴力防刷,不但防机器人,真人都不行。

4.更改抢票规则,反正都是拼手速,拼网速,拼人品,何必这么费劲大家一顿刷刷刷呢?写个算法分配下吧。

供需是主要矛盾,供大于求必定导致各种买不到票,没办法。

有些看官想学习高性能,高并发,分布式网站架构设计,我真心也不会......

建议看看看《大型网站技术架构_核心原理与案例分析_李智慧》,《大型网站系统与Java中间件实践》这两本书,《Hadoop实战》这本也不错。

由于12306这个开放性问题太大,我就只能说下为什么看到票却买不到的最基本情况,权当抛砖引玉吧。

12306网站是全世界最繁忙的网络之一,由于大量的人集中在某个时间点大量访问该网站,导致网站的并发处理能力要求非常高。我是个it小菜鸟,就给没有计算机基础的各位看官讲讲皮毛知识,大牛莫笑。

网上有这么一个统计图:

 

 

过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?

 

 

1.网站是怎么运作的。

一个用户想知道现在有没有票,于是打开网页,网站的后台就去查看自己的数据库,检索下有没有用户需要的数据,然后将结果展示到页面上,就形成了页面上的余票信息。

然后用户看到:嘿~有票!买买买!点击购买后,网站后台将用户订票的信息在数据库中更新一下:北京到巴黎的票100张变成了99张,然后购票成功。

我这里说的很简单,没有提到支付环节与退票,咱们先看这个简单的例子,画个图大概是这个样子的:

 

 

过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?

 

 

2.当有101个人都在抢票时候呢?

悲剧了,现在抢票更接近真实了,在早上8:00:00,有101个人同时要抢这100张票,会发生什么呢?对于一个人来说,网站实行“查看有多少票”(检索数据库),“买一张票”(修改数据库)的时间非常快,大约在50ms以内,所以很顺利就执行了。但是101人同时点击购买呢?全按照上图的简单流程,就多卖了1张票!所以需要再加一层检查:

由于不止一个人同时买票,所以看到票数一瞬间与点击买票的一瞬间实际上剩余的车票数量发生了变化!因此买票时候会再次检查余票。如下图,虽然红框内同时发生,不过你网速手速不行......

 

 

过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?

 

 

所以,你看到有票但是买时候没票

3.上百万人同时访问一个网站呢?

基本与上边步骤都一样,不过网站后台把用来给用户看的数据库与用来给系统改写的数据库拆开了。也就是说有一个(多个)数据库专门是给用户读的,有一个数据库专门是用来做加减操作的。它们之间每隔一定时间就把内容同步一次。(用来改写的数据库叫主库,用来读取的数据库叫从库,一般情况下主库只有一个,从库有很多个。主库的数据每隔一段时间同步到从库中)

查看票数时候只访问从库:还有票哇,好开心!

 

 

过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?

 

 

买票时候改成了访问主库:你妹!说好的有票呢!

 

 

过年回家抢票,12306的余票是怎么计算的,具体的思路是什么?

 

 

最后:实际应用中12306流程比这个复杂的多,比如同时10人抢1张票给谁?这么大访问量我带宽扛不住怎么办?由于列车太多,少一张票就会影响整个列车线,计算量太大怎么办?40分钟等待时间车票怎么办?所以这里只列举了正常情况下比较简单的逻辑,权当一看。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2021-07-26 07:47:37

2013-09-12 10:50:13

猎豹浏览器12306抢票软件

2014-12-22 11:07:18

2013-12-09 14:21:45

2014-01-02 14:14:09

12306抢票软件

2015-03-18 15:05:12

12306验证码

2020-12-18 08:55:20

Python火车票代码

2022-04-27 13:36:18

12306铁路12306

2014-01-03 09:15:39

2019-01-23 16:20:30

Python火车票程序员

2018-01-02 09:56:04

Python12306火车票

2019-12-30 07:00:51

技术研发系统

2019-10-29 10:05:17

12306 高并发系统架构

2019-01-07 14:43:40

Python抢票刷票

2014-01-17 14:39:18

12306 抢票

2020-01-13 07:42:01

技术研发指标

2021-04-21 07:23:01

Python抢票工具

2019-12-24 09:44:02

界面12306系统

2019-12-30 18:14:48

网络购票微软技术

2013-01-22 17:39:57

360浏览器抢票专版

同话题下的热门内容

该不该将单体架构迁移到微服务?生成性对抗网络——数据生成的高级解决方案SpringBoot对Spring MVC都做了哪些事?(四)软件架构中的跨层缓存技术人生 | 如何设定业务目标SpringBoot:如何优雅地进行响应数据封装、异常处理?为什么策略梯度法在协作性MARL中如此高效?终于有人把灰度发布架构设计讲明白了

编辑推荐

终于有人把Elasticsearch原理讲透了!花了一个星期,我终于把RPC框架整明白了!拜托!面试不要再问我Spring Cloud底层原理陌陌基于K8s和Docker容器管理平台的架构实践收藏 | 第一次有人把“分布式事务”讲的这么简单明了
我收藏的内容
点赞
收藏

AISummit人工智能大会