原创

Java架构师方案——CTO说:“小王,设计并落地一个类似嘀嘀的打车后台派单系统吧”

1. 今天接到了CTO的任务

某一天,突然CTO拉我去开会,说道,“小王,公司决定开展打车业务,技术方案你这边能提供下吗?“。

为了不辜负领导的信任,晚上回去就肝出来了打车软件的后台派单系统。第二天就将系统的设计的思路、系统概要、未来系统的发展路线做了简单的汇报。

下面就简单介绍下我设计的打车软件后台派单系统的设计思路和技术实现思路。【本故事纯属虚构】

2. 打车派单系统概要设计

打车软件目前top的公司,应该算是滴滴了,大家都应该用过滴滴软件。在使用滴滴打车的时候,相信大家都遇到过下面的一些情况:

情况一:选择完起始地点和终点信息后,发出订单【不出意外,后面会称为行程单】立马就有司机接单成功,然后司机往你这开。

情况二:在偏僻的地方,例如北京的城郊,你发出一个行程单,app上显示一直未有司机接单,然后你要么一直空等着,要么取消订单选择其他交通方式。

情况三:在城市的CBD、天气晴朗的玉渊潭门口、演唱会结束后的门口、晚上下班后的公司楼下。这些场景下,你发出一个行程单,显示前面有几十个甚至几百个人在排队,你需要等待很长的时间才能有司机接你的行程单。

情况四:在情景三情况下,打车app显示前面有100多个人在排队中,你就会将订单取消,准备选择其他交通方式,但当你走了一段距离后,再使用打车app,发现新发出的订单不再排队了。【瞬间一脸疑惑了!】

从上面经常出现的场景,我们就可以知道,后台派单系统派的单其实就是乘客发出的行程单。然而行程单除了出发地和目的地不一样外,其他属性没有太大区别。当然出发地还有另外一个重要的属性体现,那就是订单发出的GPS经纬度数据。
class TripOrder {

private String userName;//用户名
private String departure;//出发地点
private String destination ;//目的地
private int latitude;//维度
private int longtude;//经度

}

上面三个场景还涉及到一个概念,就是排队。也就是说,在热闹的地方,发出的行程单就会非常多,但是因为这时候滴滴司机就成了稀缺资源了,不是所有的用户都能打到车,所以打不到车的乘客就需要排队,而代替乘客排队的就是他们发出的行程单了。

因此,用户的行程单就会进入一个队列里面,而司机就是从这个队列里面去接单的,每次都是去队列里面pop出来一笔行程单,然后进入行程单的下一阶段业务:接乘客,提供交通服务【接下来的就不是本文探讨范围了】。

emmm....,说到这里,是个技术专家都已经知道了整体的系统设计方案了吧。如果你是个小白,那没关系,先收藏,以后再看。

3. 打车派单系统核心逻辑

说到核心逻辑,其实上面的概要模块已经说道了。打车业务的整个业务过程,最重要的业务活动是乘客发出行程单,以及司机去行程单队列接单。

现在有个问题,你如何将北京市所有的乘客的行程单放入到队列去维护,你不可能将所有的行程单都放到同一个队列中去,然后让所有北京司机都去队列里面接单。这种设计方案显然是不可取的。

那如果不是放在一个队列,而是进入不同的队列,那有该如何拆分队列呢?

我们知道,每个行程单都有GPS经纬度数据,我们能不能根据这个特有的信息来设计维护队列呢?思路就是:让每个乘客的行程单进入到离他最近的队列中去。这就是最核心的逻辑点。

到这里,其实大家都已经明白了,如何去设计维护一个城市的行程单队列。但是对于打车派单系统来说,最难的不是如何实现派单,而是动态调度司机的资源,因为城市的每个角落的情况是无法预先知道的,而滴滴司机的分布情况在没有干预的情况下是未知的。如果某地出现大量的行程单,你再调度司机往那里赶,可能司机到了,而乘客的行程单都已经取消了。

所以,在我们使用打车app的时候,才会出现场景三那样的情况。反正目前没有看到任何一家平台能完美解决这些打车问题。在这里也没有这方面的解决方案。

另外,乘客除了发出行程单,还会有取消行程单的活动操作,因此你的系统还要支持从队列中删除对应的行程单,而且乘客还需要在app上看到行程单的排队情况,所以每个行程单的前面排队情况还要实时更新并推送给用户app。

4. 派单系统长远发展规划

高可用性建设

刚也说到了这个平台的问题,对于平台的发展,派单系统最重要的还是高可用性,因此派单系统的长远发展,高可用性的相关建设是非常重要的。滴滴平台之前就发生过好多次线上事故,好长时间无法使用滴滴打车软件,乘客无法发出订单,司机无法接到订单。派单系统是多个核心的一个业务系统,不可用就等于公司业务无法进行。

行程单拥挤情况的改善

上文提到的场景三问题,目前没有任何一家打车平台能解决,因为生活中有太多的情况无法预估。提前预估行程单的分布情况,引导更多的司机资源聚集到行程单密集的区域。

派单场景多样化支持

本文提到的派单场景还比较简单,其实派单还需要支持更复杂的业务,例如拼单业务,如果乘客选择拼单,那么行程单被司机接到后,还没有结束处理,还需要跟后续的新订单进行行程路径的对比,如果相似度高,就行程拼单。甚至是多人拼单。

5. 测试派单系统

派单系统第一个版本落地建设好后,选择了某一区域进行简单的测试,发现系统总共维护了4个队列,如下所示:

127.0.0.1:6379> keys *net_point*
1) "net_point:1044:361"
2) "net_point:1045:361"
3) "net_point:1044:360"
4) "net_point:1045:360"

对列信息是根据gps数据得到的。因此在测试的固定区域内,系统安排了4个队列来维护这篇区域的行程单,然后这篇区域的司机可以去对应的队列中接单。

完整的demo项目,目前是不对外开放的,请关注公众号“前沿科技bot“公众号,待优化完成后开源给广大架构技术爱好者。

alt

正文到此结束
本文目录