大作业
核心业务:配单解决方案
配单的目的是为某个快递员匹配 5km 以内的订单,并推送给快递员,重点在于及时获取快递员的位置和订单的取件位置并进行距离计算,订单的取件位置一般下单后不会改变,而快递员的位置需要即时上报,这些信息可以放在缓存 Redis 中,可以利用 GEO 数据结构存储,利用 Redis GEO 命令计算匹配的位置,这样减少应用服务器的压力,并将相应的订单发送消息队列中,推送服务消费消息通过 ws 协议传递给不同快递员 5km 以内的订单。
Redis 缓存设计如下:
快递员信息使用 hash: key 使用 kds:locations:城市名,hashKey: longitude hashvalue:经度,hashkey:longitude hashvalue:纬度,hashkey:emId,hashvalue:快递员 id,位置更新由快递员及时上传。
已支付订单信息使用 hash,key 使用 pay:order:城市名:orderId,每个城市单独保存已支付订单,hashkey 使用订单 id,hashvalue 使用订单信息 json 表示,当订单状态变更为其他状态时进行对应删除,获取时通过 key 和订单 id 获取。
已支付订单位置信息使用 GEO,location-set 使用 order:locations:城市名,比如深圳 shenzhen,longitude 经度, latitude 纬度,location 订单 id,当订单状态变更为其他状态时进行对应删除,查询某个快递员 5km 的订单,利用 georadius 命令获取订单 id 列表,并获取订单信息,检查订单是否已推送,未推送的情况下发送到快递员对应的消息 topic 中,这个任务可以异步进行,有新的订单时或者快递员位置变更时重新执行。
快递员订单已推送信息使用 list,key 使用 快递员 id:notice:order,value 表示已推送的订单 id。
快递员 5km 以内的订单信息使用 redis 消息,topic 使用 order:快递员 id,消息内容使用订单信息 json,定时任务消费 redis 中消息并发布到消息队列服务器对应的队列中。
后续改进:
以上通过两点位置的经纬度计算距离的方式并不符合实际场景,实际路线不是直线,这样需要依赖第三方地图服务计算,提供快递员的位置及订单的取件位置,获取匹配的订单位置,思路跟上面的一样,结构不用调整,计算则交给第三方,获取快递员位置信息和所在城市的已支付订单位置信息,然后调用第三方获取匹配的经纬度地址,最后获取对应的订单。
评论