本文介绍一个餐饮系统的排队送券需求,针对该需求进行边界划分和技术实现方案的过程。
1、需求提出
还是前文说的互联网餐饮系统,提供了餐厅排队叫号能力。
因为有些热门餐厅,吃饭的人太多了,就出现了很多排队时间长,放弃排队就餐,转去其它餐厅。
为了挽留这些用户,餐厅提出需求,要为排队等待时间长的用户,发放优惠券。
需求主要内容:顾客排队超过30分钟还没就餐,送一张8折优惠券。
2、设计与实现
该餐饮系统,已经拆分有2个模块:
- 排队叫号服务,负责发号、排队、叫号业务
- 营销活动服务,负责发券、票券核销等业务
2.1 初始设计
研发人员初步设计了一下,实现步骤:
- 顾客取号,把该取号信息,投递到30分钟的延迟队列;
- 叫号后,会更新该排队号的状态为已就餐或已过号;
- 延迟队列的消费者,消费到消息时(这个号过了30分钟)
- 如果该号状态不是排队中,则德育该消息;
- 如果是排队中,调用营销服务的发券API,进行发券。
经过评审,问了研发一个问题,这个需求是不是固定的?有没有可能进行变化?
研发说目前收到的需求就是:
顾客排队超过30分钟还没就餐,送一张8折优惠券
后面会不会变化,怎么变化没了解过。
2.2 业务梳理
我们评估了一下,不同的餐厅不太可能是同一个时间方案,也有可能赠送不同的优惠;
再找产品经理沟通,产品答复,目前收到的用户需求就是这个,未来不排除变化可能,
如果等待时间变化,比如时间由30分钟改成40分钟,要改排队的代码并发布;
如果赠送优惠变动,比如送券类型修改成其它的券,也要改排队的代码并发布;
那么排队业务和送券业务,不应该放在一起啊,创建券、发券、核销这些都应该是营销服务的业务;
于是,重新梳理的业务边界,并设计流程如下:
评审没有其它问题,无论营销活动怎么变化,排队这边都是不用改动的,
按这个流程排入迭代并进行开发去了。
2.3 进一步业务梳理和优化
事后我对这块业务复盘,发现还有1个当时未考虑到的细节点:
- 如果顾客参与了排队,但是未就餐就走了,此时是否要送券?
经评估不应该送,于是需求变更为就餐时,超过30分钟才送券,避免用户薅羊毛啊,哈哈。
这样就不需要延迟队列了,只需要监听排除服务的事件,就可以完成需求了,技术的复杂度又降低了!!!
- 数据需要在队列里等待30分钟,有时排查问题会比较麻烦,需要队列检索工具;
- 如果就餐40分钟才送券,变成需要多个不同时间的延迟队列,更复杂了;
- 延迟队列有数据积压风险,顾客多了,延迟队列可能内存暴了;
这个需求变更唯一的缺点,就是用户在等了30分钟时看不到券,一定要就餐才能看到,
这一点,完全可以通过用户引导说明来解决。
于是,最新的设计流程如下:
注1:上图中,营销服务需要调用排队服务的API,查询排队信息,这个API是现成的,因为排队服务本身就要提供API给客户端查询排队等待信息,含排队时长、前面还有多少号等等。
注2:这里有一个思考点,在营销服务那边把开始排队的消息保存下来,后面叫号就餐时,查本地的排队信息,计算时间,是不是可以?
答案是否,原因如下:
- 排队可能被取消,那营销服务还要消费取消事件,逻辑变复杂了,可能还有其它变动,比如号给另一个人,可能手工修改排队开始时间;
- 营销多了一份排队存储数据,营销服务这边还要考虑后续的排队数据清理工作。
3、小结
精通业务
深入理解业务,能正确识别业务边界,比如这个排队送券的需求:
- 送券是一种营销活动,本质上与排队业务无关,类似于支付成功要发货,但是发货并不属于支付业务;
- 对营销活动的创建、管理、分配、核销,都应当是营销的业务范畴;
- 排队信息,包括排队数据是否有效(被取消)、排队时长这些都是排队服务的业务范畴;
- 营销服务需要设计活动,必然要了解一部分排队业务,如排队消息类型、排队时长,但是能不介入太深就不要,比如这个业务里,可以不关心排队取消信息。
单一职责,减少耦合
从实现的角度看,在排队服务里实现送券能力,能快速开发和实现,
但是最大的缺点是业务耦合:排队掺杂了营销活动的业务,不利于后续的修改、扩展,
比如:排队改成45分钟送券、或者30分钟送果盘,而不是券;比如要区分性别,男士和女士送不同的优惠等等;
最重要的问题点:营销服务不是核心服务,是增值服务,而排队服务应该是正常的基础服务,外围服务的故障,不应该影响到基础服务;
而耦合业务的话,如果送券业务出问题,可能导致排队业务也受影响,故障概率高,用户都无法排队,可能就跑了;
而如果营销服务故障,餐厅还可以通过线下打折处理来解决。