V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mobaijun
V2EX  ›  程序员

作为程序员,你可以开发一个 12306 嘛

  •  
  •   mobaijun ·
    mobaijun · 2023-01-05 11:01:29 +08:00 · 17208 次点击
    这是一个创建于 688 天前的主题,其中的信息可能已经有所发展或是发生改变。

    或者在原理上该如何实现一个 12306 ,技术难点有哪些,欢迎大家讨论

    175 条回复    2023-01-09 12:46:46 +08:00
    1  2  
    1harry1
        101
    1harry1  
       2023-01-05 16:33:26 +08:00
    学习一下
    ajaxgoldfish
        102
    ajaxgoldfish  
       2023-01-05 16:36:24 +08:00
    先能抗住各大商家的爬虫再谈其他的。没这么简单的,最后还不是让阿里干的吗
    RedisMasterNode
        103
    RedisMasterNode  
       2023-01-05 16:39:25 +08:00
    @Jinnyu 有一丢丢感兴趣,朋友你这个“前员工”具体是指哪家公司的前员工呀,或者换个问法,12306 它的开发是属于什么企业管的(比如是私企开发的还是国企开发的还是其他形式)
    saintatgod
        104
    saintatgod  
       2023-01-05 16:40:50 +08:00
    提出这个问题的不知道是产品经理还是说开发,如果是开发,建议你写一个类似的东西,实现核心算法就可以,记得叫上支付流程,测试以下并发。如果是产品经理,麻烦把买火车票这个业务逻辑的搞清楚再说,包括售票 /退票 /改签 /预约 /防止外挂 /预留票 /支付等等这些业务逻辑搞清楚再说。
    hyqCrystal
        105
    hyqCrystal  
       2023-01-05 16:41:49 +08:00
    我不能
    Jinnyu
        106
    Jinnyu  
       2023-01-05 16:42:01 +08:00
    @RedisMasterNode #103
    明面上不允许招人, 所以是进的下级单位, 但都是做 12306 的业务.
    这些公司统一归属 中国铁道科学研究院 . 在海淀大柳树 (北交大旁边)
    0o0o0o0
        107
    0o0o0o0  
       2023-01-05 16:44:31 +08:00
    @sillydaddy
    铁路一个人买两张票时间不能有重合、 铁路可以改签,这都涉及到多个车次之间的关系。
    就算是一列车,那么人可以买长乘短,也可以买短补长,如果中途出去了就会空出座位,如果补短了下一站满载了没法上人,其次还可以换坐席,那么发生这些事情之后如何分配也需要计算,况且虽然是一列车,但是有十几个站,每两个站之间都是不同的票,是不同的价格,并且还有站票 二等 一等 商务,每次有人买一个票和这个票有交集的路程就需要重新计算,实际上就算是一个班次也是很复杂的。
    Jinnyu
        108
    Jinnyu  
       2023-01-05 16:46:12 +08:00
    @0o0o0o0 #107 席位种类计算规则不对
    铁路局只管放票, 具体什么席位铁路局是不 care 的
    只有 12306 才 care 是什么席位
    watzds
        109
    watzds  
       2023-01-05 17:18:18 +08:00
    @kekxv #14 预先分配好就行了,都是抢分配好的区间票,最后发车前再清理一下给候补
    又不是实时计算的
    nash
        110
    nash  
       2023-01-05 17:20:16 +08:00
    说能做的不是前端就是产品经理
    watzds
        111
    watzds  
       2023-01-05 17:24:10 +08:00
    @0o0o0o0 #107 破系统,预先分配好的区间票,A -> B -> C ,A -> B 没票了,A -> C 却还有票,哪有什么实时计算
    ily433664
        112
    ily433664  
       2023-01-05 17:25:26 +08:00   ❤️ 1
    @cnkuner #42 然而实际上就不是这样的,现在是每个区间的票都是设定好的,根本就不会同步增减
    caqiko
        113
    caqiko  
       2023-01-05 17:25:29 +08:00
    @Jinnyu

    可以具体分享一下前置性检查是什么吗?
    我感觉最大的难度是节假日放票时要满足选座需求,短时间大量购票人排队,计算量很大,库存每变动一次都要计算剩下的票怎么更好的满足其他购票人。
    watzds
        114
    watzds  
       2023-01-05 17:26:08 +08:00
    @nash #110 因为产品经理有权改需求,实现不了就变通一下,不是那么死的,最后把票卖出去就行了
    watzds
        115
    watzds  
       2023-01-05 17:27:11 +08:00
    @ily433664 #112 估计这就是阿里给的优化方案,不是从技术上去优化,而是从需求上
    Jinnyu
        116
    Jinnyu  
       2023-01-05 17:31:02 +08:00
    @caqiko #113
    我说的这个检查不是只余票数量的检查
    是一些属性 /规则 /()保密)上的检查

    余票数量不是在这一步计算的
    Promtheus
        117
    Promtheus  
       2023-01-05 17:31:59 +08:00
    其实光嘴炮设计的话,我能手搓操作系统。至于落地么,只会写 hello world
    huobazi
        118
    huobazi  
       2023-01-05 17:32:09 +08:00
    开发个淘宝也就几百块钱。。。gou 。。。。tou 。。。。
    Lexgni
        119
    Lexgni  
       2023-01-05 17:32:44 +08:00
    可不可以用 bitmap ,多少个座位就定义多少个,然后每个格子代表一个站点,查询座位就查区间,区间有一个为 true 就说明被占了
    Jinnyu
        120
    Jinnyu  
       2023-01-05 17:34:57 +08:00
    @Lexgni #119
    那么在巨大的流量面前
    如何保证数据的同步性呢 (笑
    sillydaddy
        121
    sillydaddy  
       2023-01-05 17:39:04 +08:00
    @watzds #115
    预设的票数更合理吧,
    一是因为预设票数有背后统计数据的支撑;
    二是实时计算有明显的问题:因为订单是按时间先后提交的,如果短途先提交订单,那么长途就都给占用了。分配车票肯定不能这么明显的受订单次序的影响,如果要给长途票预留一定的数量,那不又回到统计长短途比例的思路了嘛。
    Chinsung
        122
    Chinsung  
       2023-01-05 17:39:40 +08:00
    这种系统你说复杂吗,也不复杂,但是需要相关专业的业务知识和一定时间的业务沉淀才可以花时间做出来,很多人说的复杂的锁票和分票逻辑,这个逻辑难道以前在线下买票的时候就不用考虑吗?这部分反而是老早就设计好的,只是上互联网系统以后,上游的高并发如何不打挂系统,如何设计高效的队列和风控,这些才是互联网场景需要额外考虑的
    Chinsung
        123
    Chinsung  
       2023-01-05 17:42:47 +08:00
    @ajaxgoldfish #102 你好牛,你但凡去知乎搜一下也不至于说这种话
    sillydaddy
        124
    sillydaddy  
       2023-01-05 17:47:01 +08:00
    @0o0o0o0 #107
    你说的这些里面,都不会影响各车次、各区间、各时间的并发独立性啊。我这里说的并发独立性,是指数据的写入。

    比如“铁路一个人买两张票时间不能有重合”,这个只要查询一下这个人已经买的和将要买的票的信息就可以了,只涉及读取数据。
    0o0o0o0
        125
    0o0o0o0  
       2023-01-05 17:50:44 +08:00
    @watzds 因为 a->c 是长途,优先给长途很正常,也算是一个规则吧,怎么就不需要实时计算了。。。
    @Jinnyu 明白了。。。
    x86
        126
    x86  
       2023-01-05 17:52:14 +08:00
    你是上头派来打探报价的吧?正常价位 2w ,包服务器 3w ,别被其它公司坑了!
    leeton
        127
    leeton  
       2023-01-05 18:01:38 +08:00
    任意坐车,下车支付。😅
    wtfedc
        128
    wtfedc  
       2023-01-05 18:04:35 +08:00   ❤️ 1
    @xloger 分布式集群早流行起来了,扛流量现在都不是什么问题,单纯的高并发架构,拉个大型互联网公司的技术组长就能给你讲明白。要说流量规模,12306 也比不上双十一。难点还是在数据结构,动态库存。多读多写的场景,一张票影响 N 多票,想想就是噩梦。
    0o0o0o0
        129
    0o0o0o0  
       2023-01-05 18:16:59 +08:00
    @sillydaddy
    如果同时买好几张票,那就要涉及到同步了,因为上面说每个车次都是独立控制。
    如果是改签,那么需要买新票后退原票,如果改签不成功那就不能退票,这个也涉及到同步问题吧。
    ChristianSwift
        130
    ChristianSwift  
       2023-01-05 18:24:15 +08:00 via iPhone
    @DOLLOR 然后丢给 ChatGPT 是吧
    wtfedc
        131
    wtfedc  
       2023-01-05 18:25:29 +08:00
    @Lexgni 每次扣库存,以及变更后的余票查询,就要遍历所有座位(普通车次在 1000 个左右)做一遍运算,站与站之间还有多个车次,感觉效率并不高
    jhdxr
        132
    jhdxr  
       2023-01-05 18:25:44 +08:00
    @me221 就这种帖子,嘲讽才是正经讨论。你列的那几个回复撑死也就能做到把票卖出去,最多再加上不超售。然而实际上 12306 还会根据不同区间不同日期预留票。还有比如选座是否要连座之类的。
    watzds
        133
    watzds  
       2023-01-05 18:28:28 +08:00   ❤️ 1
    @wtfedc #128 每个区间的票都是预先分配好的,哪有一张票影响 N 多票
    watzds
        134
    watzds  
       2023-01-05 18:33:11 +08:00
    @0o0o0o0 #125 预先分配好,不是更容易实现吗,干嘛自寻烦恼用实时呢
    mxT52CRuqR6o5
        135
    mxT52CRuqR6o5  
       2023-01-05 18:40:49 +08:00
    我听说区间票根本就没有什么动态分配,都是提前规划好的固定数量,这种情况下还难吗?
    0o0o0o0
        136
    0o0o0o0  
       2023-01-05 18:43:38 +08:00
    @watzds 预先分配也是要早点出票的,并且还会有退票、改签的情况,之后肯定还是得实时计算吧,现在看起来遇到高峰期是先预分配也就是候补,然后过几天之后放票就是实时计算的了,而且越靠近发车时间越需要把票尽量卖出去,就越需要实时的。。。
    wtfedc
        137
    wtfedc  
       2023-01-05 18:45:48 +08:00
    @watzds 举个理想化例子,不考虑区段超卖,短途不卖的政策。某个北京到广州的车次,我买了 1 张北京到保定的票,这趟车所有始发站是北京的票库存都要调整;我买 1 张新乡到郑州,那这趟车所有囊括这个区间的票库存都要变动。
    monologue520
        138
    monologue520  
       2023-01-05 18:47:38 +08:00
    我可以画一个界面 (手动狗头
    stonelf
        139
    stonelf  
       2023-01-05 18:58:33 +08:00
    @sam384sp4 锁都没有设计出来,并发写如何互斥?单线程操作吗?
    me221
        140
    me221  
       2023-01-05 19:08:11 +08:00   ❤️ 2
    @jhdxr
    #132

    楼主正文是「或者在原理上该如何实现一个 12306 ,技术难点有哪些,欢迎大家讨论」

    这是一个问题, 会就答, 不会请沉默.

    不要冷嘲热讽.

    「嘲讽才是正经讨论」你真给我看笑了.
    sillydaddy
        141
    sillydaddy  
       2023-01-05 19:40:24 +08:00
    @0o0o0o0 #129
    改签是先买后退,不涉及同步。因为票总是能退的:买不到就改签失败,无需退票;买到了就改签成功,总能退掉原票;
    买多张票也是一个道理。
    AyaseEri
        142
    AyaseEri  
       2023-01-05 20:22:30 +08:00   ❤️ 1
    @watzds 不是阿里给的方案,铁路的业务本来就是这样的。票额预分配制度早于 12306 的出生。
    tylerdurden
        143
    tylerdurden  
       2023-01-05 20:23:55 +08:00
    @hfl1995 #9 人才。
    RedisMasterNode
        144
    RedisMasterNode  
       2023-01-05 20:29:43 +08:00
    @Jinnyu 原来如此~感谢
    mike2016
        145
    mike2016  
       2023-01-05 20:52:43 +08:00
    我和朋友做过火车票的项目,如果楼主是想尝试项目的话,可以探讨一下
    watzds
        146
    watzds  
       2023-01-05 21:21:54 +08:00
    @wtfedc #137 预先分配的区间票,只有该区间的库存要调整,查票不都是查区间,哪有查单个点的

    A->B, A->C, B->C ,数量都是预先分配好的,不会一上来 A->B 把所有票卖完了
    watzds
        147
    watzds  
       2023-01-05 21:24:54 +08:00
    @0o0o0o0 #136 靠近发车时间,也只要跑定时任务,先分配给候补的,一般就没票了

    如果候补少还有票,说明不是热门的,靠近发车时间请求量应该也没这么大了,而且还能限流,大了直接失败
    ajaxgoldfish
        148
    ajaxgoldfish  
       2023-01-05 21:32:22 +08:00
    @Chinsung 知乎上搜过了也看完了,还是老观点《没这么简单的》,反而觉得更牛逼了。
    watzds
        149
    watzds  
       2023-01-05 21:45:58 +08:00
    @ajaxgoldfish #148 知乎哪个回答啊,我看到一个阿里云的人,说是幕后码农,我看就是个卖服务器的,又没参与研发,和我们一样的,在那儿瞎讨论
    shxlxa
        150
    shxlxa  
       2023-01-05 22:55:15 +08:00 via iPhone
    @loading 真是张口就来
    mooyo
        151
    mooyo  
       2023-01-05 23:06:56 +08:00
    不考虑并发很简单,考虑并发也能做,但肯定不是一个人的工作量。
    lujiaxing
        152
    lujiaxing  
       2023-01-05 23:35:23 +08:00
    不要在这里吹牛. 我简单的介绍一下 12306 的放票逻辑, 你们可以想想.


    1. 席位占用. 拿 K598/599 次 (包头 ~ 广州) 举例, 假设某人买了 呼和浩特 ~ 衡阳 区间. 那么 包头 ~ 北京丰台, 呼和浩特 ~ 长沙 等 呼~衡 之间任意一个区间同一席位不得再售卖. 你们可以想想这中间有多少种组合.

    2. 席位复用. 同样 K598/599 假设某人买了 呼和浩特 ~ 衡阳 区间. 那么理论上 衡阳 ~ 广州, 包头 ~ 呼和浩特区间同一席位可以重复发售.

    3. 限售. 比如 K386 硬卧限售郑州以远. 硬卧优先卖给 成都西 ~ 郑州以及去更远地区的的旅客. 直到开车前 24 小时解除限售. 不同车站放票数额也不一样. 一般以管内大站优先, 外局以大站为主. 一般一个或几个连续车厢的席位集中分配给一个大站. 即便是别的车厢人已经超员压弹簧, 预留的车厢还是要预留出来.

    4. 防牛.
    1) 退票不得马上回到票池, 退回去的票随机放出.
    2) 放票不再集中在某个时间点, 而是分时段随机均匀的放出.

    5. 车型. 中国大陆铁路系统主要的铁路列车车底包括: 25B, 25G, 25K, 25T, BSP, 25Z, 25DT 等. 不同车厢定员不一, 定价不一. 有空调与非空的区别. 火车票票价包括: 里程费 (票价率 * 里程), 空调费, 加快价 (K, T, Z 等都有) 等. 同一线路不同车次不同车型价格都可能会不一样.

    6. 通票. 这个就不展开了. 听说过铁路签证不?

    7. 窗口票. 考虑到中国大陆尚有很多的文盲 /老年人不方便使用 12306, 因此每个车次每一个区间都要预留一定量的窗口票以方便这些人使用传统的购票方式购票.



    我只是简单的说一下铁路售票的逻辑. 实际比这还复杂很多... 就这些需求你们自己想吧. 看能不能做出来.
    lujiaxing
        153
    lujiaxing  
       2023-01-06 00:19:35 +08:00 via Android
    @sam384sp4 想啥呢. 中国有多少车次你有没有想过? 我们理想化一些, 就按春运期间都是用最普遍的 25G 车底, 18 节编组 (9YZ + 4RW + 5YW + 1CA ) 记:

    8498 次 /日 * (9 节 * 118 (人, YZ25G) + 112 (人, YZ25G) + 超员 (按 30% 计) + 4 节 * 36 (人, RW25G) + 5 节 * 66 (人, YW25G)) * 31 (平均每车次停靠车站数) = 517919108
    一天记录所有的车次所有席位就要用 5 亿 1791 万 9108 个标志位. 我们春运期间预售期 15 天, 517919108 * 15 = 7768786620....

    你找一个能吃得下 77 亿数据还能高并发的数据库产品吧...
    lujiaxing
        154
    lujiaxing  
       2023-01-06 00:20:36 +08:00 via Android
    @lujiaxing 19 节, 忘了一个餐车了
    liprais
        155
    liprais  
       2023-01-06 00:32:02 +08:00
    @lujiaxing 12306 用的 gemfire,数据量级跟你算的差不多
    exploreexe
        156
    exploreexe  
       2023-01-06 02:19:23 +08:00
    依稀记得当年 12306 上线的时候被全国人民喷成了煞笔,就 12306 的业务复杂度和并发量 真不是一个简单的项目。
    fronted
        157
    fronted  
       2023-01-06 09:42:35 +08:00
    好多阴阳怪气的玩意,只是讨论个问题而已不至于吧
    a852695
        158
    a852695  
       2023-01-06 09:59:52 +08:00
    一来就开始写代码?想下实际的业务诉求,我看了一圈好像没几个把需求给整明白了的。
    wtfedc
        159
    wtfedc  
       2023-01-06 10:10:18 +08:00
    @watzds 我说的就是区间,北京到保定是区间,新乡到郑州也是区间,他们的库存,影响其他区间。照你的逻辑,A->B 不影响 A->C ,这就没法聊了。
    Ocean810975
        160
    Ocean810975  
       2023-01-06 10:21:00 +08:00 via Android
    之前看 b 站 12306 的介绍,12306 的日常并发和淘宝双十一的并发是一个水平的来着。
    zxcslove
        161
    zxcslove  
       2023-01-06 10:22:49 +08:00   ❤️ 1
    阿里救世说可以休矣,开头几年没有阿里的事,后来参与也不是解决了什么根本难题,那时候已经基本稳定了。
    zxcslove
        162
    zxcslove  
       2023-01-06 10:23:07 +08:00
    最讨厌记忆修改术了
    hhjswf
        163
    hhjswf  
       2023-01-06 10:45:25 +08:00 via Android
    流量估计也就那么回事,很多灰色流量恶意流量都被滤掉,再通过行政手段,压力小很多。
    likeme
        164
    likeme  
       2023-01-06 11:34:23 +08:00
    @lujiaxing 感谢 153 楼的介绍,😂瞬间有感觉(难度很高)了
    Torpedo
        165
    Torpedo  
       2023-01-06 13:14:05 +08:00
    以我的经验,12306 这种前台逻辑再复杂,也是可以集中投入大牛去解决的。但是后台对接整个中国铁路内部的系统来说,必然是复杂的
    楼上评估项目复杂度的时候,都是站在 12306 本身,但是它后面对接的整体铁路内部的各种流程、人员,才是更复杂的。
    然后内部复杂流程又会影响了 12306 本身,导致整个项目都很复杂

    最后,我想说 12306 做的好不好,对铁道部来说收益一般。假设 12306 做的完美无缺,高峰该买不到还是买不到
    AyaseEri
        166
    AyaseEri  
       2023-01-06 13:39:14 +08:00   ❤️ 1
    @lujiaxing 都是区间预分配的,按你这实时计算复用的办法多数人根本出不了门、每趟长途列车估计得空一大半。
    winglight2016
        167
    winglight2016  
       2023-01-06 14:11:52 +08:00
    先回答 lz 的问题:可以

    原因是:一个人开发有一个人的做法,100 人的团队有 100 人的做法,但是 12306 ,个人认为,60 个人左右的团队就足够了。

    前面有很多回复认为太难,主要原因是把业务需求和非功能性需求混在一起思考,就会觉得千头万绪没法解决。另外,12306 的核心功能点就在于产品定义和售票规则,性能问题是很次要的需求,从这个角度看,一个电商系统改改就能用了,这就是我回答可以的原因所在。

    所以,真正的难点不在技术开发和实现,而在于把业务需求转换成技术方案。
    q447643445
        168
    q447643445  
       2023-01-06 14:43:05 +08:00
    开发不了. 没那种实力
    Chinsung
        169
    Chinsung  
       2023-01-06 17:34:04 +08:00
    @ajaxgoldfish #148 我们看的难道不是一个知乎?知乎不是很多参与过项目的说主要就是用了阿里的移动端架构和阿里的一些云服务,到你这就“最后还不是让阿里干的吗”?那你倒是说说阿里到底干了啥,解决了 12306 哪些解决不了的问题啊兄弟
    google 有篇 12306 优化的简单论文,在 2012 年就出方案去优化了,到你这就全是阿里干的了?
    watzds
        170
    watzds  
       2023-01-06 17:58:39 +08:00
    @lujiaxing #152 闭门造车,自己创造难度,确实够难 😅
    xxiu
        171
    xxiu  
       2023-01-06 19:40:19 +08:00
    我认为比较难,大家都在说定单的问题,我说查询的问题吧,当然查询是建立在订单上的。 后端怎么抗住每天几百亿次的查询。怎么设计缓存机制,均衡负载怎么做,怎么算集群的容量,网络的出口需要多大,自动扩缩容怎么做,后端服务集群怎么搞,怎么保障可用性,特别是像春节这种的服务可用性。 很多说简单的同学可能设计出来的架构没问题的,但是第一时间网卡就直接被打爆了。
    HankLu
        172
    HankLu  
       2023-01-07 01:39:21 +08:00
    @xtreme1 现在又水了好几页
    Vvictor
        173
    Vvictor  
       2023-01-07 09:43:48 +08:00
    有嘴就行
    junwind
        174
    junwind  
       2023-01-07 12:15:52 +08:00
    这种数据量巨大,并发巨大的,业务异常复杂的,普通人很难完成的
    lujiaxing
        175
    lujiaxing  
       2023-01-09 12:46:46 +08:00
    @AyaseEri 我没有说他放票是不是预分配机制. 但是席位复用必定是动态分配. 因为没人知道某一个区间会不会被人买掉而在前后留下两个说长不长说短不短的空闲区间. 更说不好这个空闲区间会出现在哪儿. 很有可能查询车次的时候就是固定放票 + 席位复用.
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2409 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:11 · PVG 10:11 · LAX 18:11 · JFK 21:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.