产品开发经验分享2——实时结算和t+1结算

350 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

在日常的业务开发中,对于产品设计或者技术选型,都会涉及到很多trade off,今天来讨论一下,我经常碰到的两种结算方式:实时跟t+1。

比方说,要开发一个任务模块,给用户下发了任务后,需要对用户的完成情况进行结算。举一个具体的场景,某个任务希望今天能发一篇文章,才能完成。

对于实时的结算方式来说,我们需要有实时统计的方式,能够有办法主动监听到用户完成任务。比如用户每次发完文章后,可以走消息队列,推送消息到业务系统,当感知到用户投递了稿件后,就帮他进行任务状态的结算。

对于消息队列的方式,好处就是能做到实时,坏处就是不可避免会因为意外情况,丢消息。完全不丢消息,成本比较高,我们可以采用以下几个方式来减少影响:

  1. 消息失败后,能有办法记录下来,并且有定时任务去重新执行失败的消息

  2. 兜底策略,比如用户每次打开自己的任务时,就帮他实时结算一次,前提是需要有实时的接口

  3. 对账系统,通过后台任务来轮询用户任务执行情况,并且给他更新状态。

当然,具体采用什么方式,还得看业务的支持,以及任务的业务形态。

还有一种结算方式是t+1的方式,即用于结算的数据,无法立刻产出,需要延迟到第二天产出。一些统计比较麻烦的指标,或者没有实时的消息的指标,通常需要隔天进行结算。

在我负责的业务里,通常中午12点,是各种结算数据ready的时间,因此就在那个时刻跑结算脚本。

在t+1的结算设计中,有以下几点需要关注的地方:

  1. 如何保证数据是ready的状态?通常我会要求提供数据的业务方,给我一个可以查询今天数据确实ready的方法。如果数据未ready,跑结算脚本也无意义。

  2. 结算耗时,如果结算数据量比较大,结算脚本就会跑比较久。比如12点开始结算,2点才跑完,对于用户的对外口径来说,中午12点开始结算,他根本不在乎结算数据量大的问题。所以可考虑加一个兜底逻辑,结算时间之后,用户进页面后,就给他实时结算一次。

  3. 结算任务需考虑执行失败后,有能力重新去执行,以及重新执行时的幂等性。

以上就是实时结算跟t+1结算的区别。

对于具体的任务设计,对于实时结算来讲,只需给用户两个状态,【未完成】,【已完成】。具体的时间点,可以分为任务开始时间和任务结束时间即可,最佳实践是消息队列+实时接口做兜底

而对于t+1结算来讲,需要给用户提供三个状态,【进行中】,【未完成】,【已完成】。具体时间点,可分为任务开始时间、任务结束时间(结算开始时间)、结算完成时间,最佳实践是定时任务+实时兜底接口。

可以再考虑一个问题,如果我们有实时提供结算能力的接口,该如何设计业务架构呢?

首先,实时接口≠实时结算,如果数据量到达一定规模,接口一般都会有QPS限制,我们在执行结算时必然有延迟,所以此时的任务形态,必须是t+1类型的。