去年,一部《超级快递》给大家带来了不少欢乐,除了欢笑,我们也看到了准时送达作为一种增值服务或者高端服务在快递物流行业中可能性和市场。而每天上亿的快递数量靠人肉来保证已经几无可能,在这里,我们从系统的角度来看看如何搭建一个保证快递能够准时到达的系统。
要保证快递能准时到达收件人手里,就需要能够主动及时的发现那些可能会迟到的快递,并在第一时间进行查看和处理,比如联系到快递小哥确认状态等等。
在这里,我们将快递在整个流转的过程进行拆分,当快递达到一个状态之后,确定下一个状态以及达到时间,在规定的时间内没有到达则需要通知相关的负责人进行处理,我们将快递的每一次状态的更新都写入数据库中,然后采取下面两种方案进行简单的处理:
方案一
每次更新快递的状态时与前一次状态进行比较,中间的时间差超出期望时间则报警。
方案二
定时对所有的快递状态进行检查,最近一次状态更新的时间距当前时间超出期望则报警。
__方案一__只在快递更新时做处理,对系统的压力最小,但是需要依赖快递的到达时间触发,时效性太差,快递到的越晚就越晚才发现快递迟到,往往是发现快递不能准时送达的时候快递就已经迟到了。
__方案二__发现可能迟到的快递的时效性取决去检查的周期,最坏情况下就是快递在检查之后马上就超时了,等到下次检查才能发现,而且对日均千万甚至亿级别的快递状态进行存储本来就是一个非常头疼的问题,再扫全库进行查询又会大大增加数据库的负担,很有可能查询的时间就会超过快递的超时时间。
所以,我们选用了阿里云的表格存储与消息服务的延时队列功能来解决这个难题。
快递状态存储
首先,我们将快递的每一个状态都存储在表格存储中。
表格存储很好的解决了数据规模与读写并发上的问题,单表能够支撑到万亿级数据规模,自动负载均衡能够让用户不需要做任何动作就可以将数据表的读写并发扩展到百万级别,按量付费又可以避免资源的浪费。同时,读写性能不受数据规模的影响,也不用担心数据积累之后的性能问题。
异常快递检测机制
首先,我们根据业务情况在消息服务上创建多个不同的队列,每个队列设置不同的DelaySeconds,进入该队列的消息将在设置的DelaySeconds之后才会被消费者取到。
在每一个快递状态更新时,一方面将该快递状态写入到表格存储中,以提供实时在线查询。同时,根据快递状态的超时时间创建一条消息,包括快递单号、超时时间等信息,将该消息发送到对应的队列中,比如处于揽件的某个快递需要在2小时内到达中转站,则将该快递的信息push进 __2小时揽件队列__。
超时检查系统从上述队列中取消息进行检查,根据消息中的 快递单号 在表格存储中查询该快递的最近一次状态信息,如果查到的最新状态时间大于消息中的时间,则说明该快递在超时时间内达到了下一个状态,否则该快递则有不能按时到达的风险,迅速进行报警处理。
架构优势
- 表格存储与消息服务都是高并发、按量付费产品,不需要评估业务的访问情况,再购买相应的规格,按量付费也不会出现资源的浪费。
- 表格存储的高并发优势可以在几十万的QPS下依然提供毫秒级的读写延时,从容应对超时检查系统以及来自真实用户的快递查询需求。
- 快递到达超时时间之后能够立刻被消费者也就是超时检查系统看到,大大提高了处理的实时性。
- 一个队列可以对应多个消费者,每个消息只会被一个消费者取到,所以查看队列里面的消息堆积情况,包括未到唤醒时间的消息和已经唤醒等待处理的消息数量,当等待处理的消息数量过多则说明系统处理的慢了,这个时候就可以动态增加处理节点了,节点间没有状态引入,直接去获取消息时间处理即可,部署架构又大大简化。