【开发经验】排队预约系统开发思路

背景

      前不久陪朋友参加了一场教师面试,进入面试现场时,每个人都要扫描二维码进行排队。当时扫码的人挺多的,不一会,服务器就卡主了,一堆人就开始焦急起来,因为提交报名的马上就要截止。好在过了几分钟,又可以进行排队了。等这件事平息之后,就在思考了一下,其实这次的报名的并发不是很高,并发量在100内,但是偏偏这么点并发就可以使得服务器卡主,这个教师报名排队系统的开发可能需要思考下了。

      笔者不才,也曾开发过一个排队的功能。这个并发要远远高于前面的预约面试。这里阐述下我的实现思路,欢迎大家吐槽。

一、实现思路

1.1 数据表设计

      首先,数据库设计,这里肯定有一个报名信息表,存储当前报名的开始时间、结束时间、报名标题等等。

报名信息表大概如下:

id title startTime endTime
1 北京大学教师面试报名 2021/1/1 2021/1/2
2 北京大学附属小学招生 2021/1/1 2021/1/2

报名记录表大概如下:

id user_mobile order createTime 报名id
1 132{手机号信息} 1 2021/1/1 1
2 152{手机号} 2 2021/1/1 1

      表设计很简单,报名记录表记录每一次报名的报名人和报名序号。一般这种不允许重复的数据,会在报名iduser_mobileorder三个字段上加上唯一索引,保证数据绝对不重复。

1.2 实现思路

排序问题

      比较棘手的是这个排序问题,现在一般的项目都是集群部署,在确认当前人的序号时,存在并发问题。也就是存在多个人都争夺一个序号的问题。采用redis的incr命令可以更加友好的解决这一问题。

incr命令是原子增加1,并且将增加后的值返回。操作如下:

redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21

      通过这一命令在报名开始的时候设置值为0,然后每一个人报名时,都通过incr命令获取当前排名。

去重问题

      一般情况下,每个手机号在同一个报名场景中只允许报名一次。因此去重也是一个比较麻烦的问题。如果每次都去查询数据库有没有报名记录的话,也是一个很造嫌弃的操作。

      通过redis的bitmap数据结构可以更简单高效的实现数据的去重。也许会有人使用set或者hash。虽然HashSetHashMap也同样能实现用户的去重和统计,但是如果使用HashSetHashMap存储的话,每一个数据比如用户ID都要存成int,占4字节即32bit。而一个用户ID在Bitmap中只占一个bit,内存节省了32倍。

#设置值
setbit key offset value
#例如第一次教师报名中用户userId为123的用户已经报名
setbit baoming_key_1 123 1
# 获取值
# 可查看是否已经报名
getbit key offset

      通过此数据结构,不光可以去重,也可以处理黑名单。通过如此思路,实现起报名排队的功能速度会快很多。
      思路大概是这样,欢迎大家吐槽哈。

猜你喜欢

转载自blog.csdn.net/qq_30285985/article/details/114378346