Skip to main content
  1. internet/

对于任务中心系统设计上的反思

·1340 words·3 mins·

前言 #

任务中心是一个通用层的系统,用于统一管理任务进度,对接前端的进度条组件

主要流程为:

  1. 用户触发一个任务
  2. 业务子系统对接任务中心:添加任务、更新进度和任务状态
  3. 任务中心通过WebSocket向用户推送任务状态、进度。

任务中心系统分为三层:

  1. 支撑层:统一管理任务状态、进度
  2. 中台层:管理任务和用户的关系
  3. 前台层:管理权限、与前端交互

业务子系统对接任务中心的流程为:

  1. 在支撑层获取任务id
  2. 在支撑层添加任务信息
  3. 在中台层关联任务和用户
  4. 在支撑层获取场景中未被消费的任务
  5. 执行任务并在支撑层更新任务进度和状态

解释一下为什么在第2步添加了任务后还要在第4步获取呢?这是因为在设计上假设业务子系统分为了生产者和消费者,也就是消费任务的是一个独立的worker,因此需要再次获取任务。

系统内的问题 #

问题1. 服务划分 #

任务中心将对任务的管理对用户与任务的关联进行了拆分,使得两者解耦,任务管理完全不用考虑用户,这是一个好的设计。但问题是它把这种拆分具象到了服务层。

这意味着如果业务子系统对接任务中心,需要调两个服务的API,这造成了客户的困惑(如果把任务中心看做一个产品,业务子系统就是客户):我只是对接任务中心组件,为什么需要对接两个服务?

所以,对任务的管理对用户与任务的关联应该是一个服务内部的划分,这应该是对客户不可见的。

问题2. 干涉了使用方的设计 #

在任务中心的设计中,假设了业务子系统会分为任务task1的生产者和消费者——就像对接MQ那样。这种设计是假定任务task1的消费一定是异步的。

但问题在于业务子系统实际上有自己的任务task2调度系统,它只用任务中心来更新用户的进度条。

因此,对于业务子系统来说,它从自己的任务调度系统中获取一个任务task2,然后对接任务中心,在这个task2的消费中,包含了对于task1的生产和消费。

于是,虽然task2的消费是异步的,但是task1的生产和消费却是同步的。

这对业务子系统造成了很大困扰:

  • 如果再把task1的生产和消费分开,无疑会增大开发工作量,也增加了维护工作量
  • 如果不把task1的生产和消费分开,只能在生产了任务task1后,马上开启for循环来尝试消费它。这无疑会让代码变得丑陋且难以接受。

问题3. 定位不明确 #

问题2的根本原因是任务中心对于自己的定位并不明确。它想把自己包装成一个任务调度系统,但是实际上是一个任务进度管理系统。

这一点也能从它的名字——任务中心——看出来。

也就是说,当前的任务中心的需要开发一套通用的任务调度系统,然后将其和任务进度管理模块进行组合、打包给业务子系统。

综上,任务中心需要包含三个模块:

  1. 任务调度模块
  2. 任务进度管理模块
  3. 任务与用户的关联模块

问题4. 对接繁琐 #

对外提供的对接可以进一步简化,比如1.生成任务id 2.添加任务 3.绑定任务和用户 可以简化为一个接口。对于目前的现状,这个接口还可以包括 4. 获取可执行的任务

系统外的问题 #

服务这个词很有意思,任务中心系统由几个服务组成,又服务于整个产品系统。

那么既然使用者感到不好用,为什么不提出来呢?这说明其他部门内的人对于任务中心系统的定位也不明确。对于这种不好用的东西,他们往往是自己做兼容或者自己实现一套,这显然是不合理的。任务中心系统服务于整个产品系统,这是需要加强的概念。