春运一票难求,候补抢票显威,如何设计一个候补订单系统?

春运一票难求,候补官方抢票

最近春节火车一票难求,12306系统的候补购票是一种官方支持的抢票方式。在首日票已售罄时,立即提交候补请求,系统会优先考虑候补乘客的需求。根据成功率灵活选择是否候补购票。

当旅客在12306网站购票,输入乘车日期、发到站等信息查询没有余票时,页面会在相关车次的席别余票显示列表中出现"候补"字样,旅客可根据需求点击相应车次、席别对应的"候补"区域,系统将该需求自动加入当前候补购票需求列表。候补订单提交成功后需在30分钟内完成支付,完成候补预付款支付后,候补购票订单立即生效。候补购票订单生效后,相关候补需求不可修改,如需变更,可终止订单后重新操作。兑现时,按照候补订单生效的时间顺序,优先兑现符合条件的候补需求。预付款按该单不同组合需求中票款的最高额度计算(卧铺按下铺票价计算)。

候补订单系统该如何设计?

那么如何设计一个12306火车票候补功能的系统呢?设计一个12306火车票候补功能的系统我们需要考虑的主要模块包括乘客候补系统、车票余量监控、排队、通知机制以及支付与出票等核心环节。以下是一种简化的系统设计概述:

  1. 乘客候补订单模块
  • 用户提交候补请求:允许用户对已经售罄的车次座位发起候补申请,包含乘车人信息、日期、车次、席别等必要信息。

  • 候补队列建立:系统将所有候补请求按照一定的优先级策略(如购票时间先后、会员等级等)排序,形成候补队列。

  1. 支付模块
  • 候补订单申请成功后,用户在接到通知后,应在规定时间内完成支付。

  • 支付成功后需要将消息推送到候补订单模块,候补订单根据规则排序建立候补队列。

  1. 车票余量监控模块
  • 实时对接12306票务数据库,监控各车次的退票、改签动态,实时更新车票剩余情况。

  • 当有乘客退票或者改签导致座位空缺时,触发候补队列处理机制。

  1. 候补处理模块
  • 根据车票余量变化,自动从候补队列中选择符合条件的候补乘客,为其生成车票。

  • 成功分配车票的候补请求移除出队列,未成功分配的则继续保留等待。

  1. 出票模块
  • 候补订单处理后,系统立即执行出票操作,将电子客票信息更新至乘客账户,并可下载电子凭证。

通过以上模块,构建一个高效、稳定、透明的火车票候补系统,既能有效利用票源,又能提升用户体验。

那么不同的车次、订票日期、坐席、出站、候补人数组合在一起后传统的消息队列可能无法满足我们的需求了。下面拿G521列车举个例子:

这是一个开往武汉的高铁,假如我们要在2024-02-08这天要到郑州,票没有了,我们候补订单候补了3个人,那么这个队列该怎么存放呢?

我们可以简单想下一个队列能够快速的根据车次、订票日期、坐席、出站、候补人数组合等信息快速找到队列,并消费。传统数据库无法满足这种高并发的需求,REDIS的list貌似可以试下,如果我想对某个车次+日期查询队列情况(超过一定数量,提示用户不要排队了)又不太方便,这时hash+list的组合就比较合适了。下面我们看下详细设计。

如何使用redis的hash+list实现候补队列

我们使用 Redis 的 Hash 结构来实现根据车次、车站、日期、乘车人数设计一个队列。每个车次及时间作为一个 key,车站和乘车人数作为 field,对应的值是一个队列,存放候补订单。当某个车次到某个车站有票时,可以遍历这个 key 及 field,找到第一个队列进行消费。以下是具体的设计方案:

1. Redis Hash 结构

vbnet 复制代码
Key: train:{train_number}:{date}
Field: {station}_{passenger_count}
Value: 候补订单队列

2. 举例

假设 G521 车次,日期为 2024-02-08,有 3 个乘客,站台为 郑州。

makefile 复制代码
Key: train:G520:2024-02-08
Field: 郑州_二等座_3
Value: [候补订单1, 候补订单2, 候补订单3, ...]

3. 消费逻辑

当某个车次到达某个车站有票时,我们可以按遍历该车次在该日期下的 Hash 结构的 field,如果很多票我们选择优先消费field=郑州_二等座_3的队列,如果只有一张票我们只能消费郑州_二等座_1的队列。当然还需要结合候补时间判断。

总结

  1. Hash 结构设计: 使用 Hash 结构来存储车次、日期、车站、乘车人数等信息,便于查询和管理。

  2. 队列存储候补订单: 在 Hash 结构的 field 中存储候补订单队列,便于根据车站和乘车人数索引订单。

  3. 消费逻辑: 当某个车次到达某个车站有票时,遍历相应的 Hash 结构,找到一个非空队列进行消费。

通过以上设计,我们可以根据车次、车站、日期、乘车人数设计一个队列,并通过 Redis 的 Hash 结构实现,保证了订单信息的管理和处理的高效性和可靠性。想想一些平台的排队功能是不是也可以这么搞?

相关推荐
Java水解1 小时前
Spring Boot 消息队列与异步处理
spring boot·后端
桦说编程1 小时前
AI 真的让写代码变快了吗?
后端
AskHarries3 小时前
openclaw升级和参数调整
后端·ai编程
creaDelight3 小时前
基于 Django 5.x 的全功能博客系统 DjangoBlog 深度解析
后端·python·django
菜菜小狗的学习笔记4 小时前
黑马程序员Redis--实战篇(黑马点评)
数据库·redis·缓存
zz-zjx4 小时前
harbor使用外置db,redis,存储(minio)通过pigsty安装(单机)
数据库·redis·缓存
Rust语言中文社区4 小时前
【Rust日报】 Danube Messaging - 云原生消息平台
开发语言·后端·rust
深蓝轨迹4 小时前
黑马点评--达人探店模块
java·spring boot·redis
菜鸟程序员专写BUG4 小时前
SpringBoot 接口返回异常全集|JSON解析失败/响应乱码/状态码错误完美解决
spring boot·后端·json