在我们漫长的工作历程里,想必大家都曾频繁与各类的工单需求打交道。无论是在业务流程中发挥关键节点把控作用的审核工单,还是承载着客户反馈与诉求的投诉工单,这些相似的工单需求广泛分布于各个行业与业务领域。本文旨在实现通用化工单中心,以配置化的方式,提高“所有”类型的工单的接入效率,并降低维护和学习成本。
一、工单需求的“内耗”
就拿我所在的部门举例,在财经贷后部门的发展中,产品在投诉,作业,质检等场景,陆陆续续提了30+个工单类需求,在表面上,我们不断应对着那些披着不同业务外衣的工单需求,看似丰富多样,实则内核相似。我们一次次地重复着相似的技术实现流程,尽管这些工单需求被赋予了不同的业务价值,仿佛在不断提醒着我们工作的意义。但更多时候,这不过是一次次自我麻痹罢了。
随着业务的发展,我们发现,各类工单的 “烟囱” 越来越多,数据冗余问题愈发严重,通用功能无法复用。当下,我们主要面临着以下的问题:
痛点 | 描述 |
---|---|
功能重复建设,人力反复投入,ROI低下 | 诸如统计,分单,协作,跟进等通用功能每个工单模型都独立建设一套。 |
工单生命周期无法可视化 | 工单的生命周期和状态流转,只硬编码维护在每个行为接口中,导致每个接口业务属性太强,也会增加新同学的业务学习成本。 |
工单处理流程硬编码 | 缺乏灵活性和可配置性。一旦业务流程发生变化,就需要对代码进行大量修改。 |
同时维护多套模型和代码,运维成本大 | 投诉系统,质检系统,作业系统等等,都各自维护一套甚至多套的工单模型 |
二、工单方案的演进之路
-
识别是工单数据
-
思考工单中心的设计模式
依赖抽象,而不是具体。高内聚,低耦合。
以下以投诉服务的投诉工单举例
在一个go服务里Interface是抽象接口,可以用于依赖倒置等,降低代码耦合度。
在两个不同的go服务,Interface可以看成RPC接口。
当实现类发生变化时,只要接口不变,其他模块就不受影响。
因为工单中心沉淀出来的模型肯定无法完全承接业务的工单模型,所以业务还会存储原有的高危工单模型,但是将通用功能,生命周期,执行流程等信息下放到工单中心。
-
工单中心建设的核心目标
-
通用功能沉淀
在本次建设的时候 ,不仅回顾了以往的历史需求,也结合和产品侧的规划,我们最终将工单中心的核心功能分为三块,分别是生命周期管理,通用查询能力,以及功能扩展。如下图:
-
工单的生命周期和工作流程配置方案选型
对于不同的工单,其状态机不尽相同,尽管同属于投诉域,出自同个产品团队,但是其状态的流转都存在着一定的差异。
实现控制工单生命周期和工作流程的流转的配置,目前共考虑两个方案。分别是通过 可配置化 状态机 或 流程引擎 ****实现。
### ✅流程引擎方案,参考 aha | ### 可配置化状态机方案,参考ByteState | |
---|---|---|
样例图 | ||
可配置性&灵活性 | 很强 支持通过配置文件或可视化工具来定义和修改工单流程,无需编写大量的代码。业务人员可以根据实际业务需求随时调整流程,提高了系统的灵活性和响应速度。 | 较差 状态机主要关注状态的转移,对于工单处理过程中的其他方面,如任务分配、定时提醒、数据校验等功能支持不足,难以满足多样化的业务需求。 |
性能 | 较差 工作流引擎需要处理复杂的业务流程,其设计要考虑到各种可能的流程分支、并行任务、循环结构等。这种复杂的设计使得工作流引擎在运行时需要进行更多的计算和判断,从而导致性能开销增加。(但因为工单的转流一般对时效性要求没那么高,只要能在秒级给出应答即可,所以我们在选型上能接受这一缺点) | 高 由于状态机的逻辑相对简单,状态转移的判断和执行速度较快,对于高并发、对性能要求较高的工单系统部分场景,能够快速响应和处理。 |
扩展性 | 强 ****可以自定义原子节点,后续可供其他的流程配置直接使用。使用的时候只要关注出入参即可,无需关注实现逻辑。 | 较差 无法将一些通用能力继承成原子节点编排到状态机上。 |
中心化 | 是 | 是 |
学习成本 | 差不多 | 差不多 |
其他功能 | 较多,且可扩展能力强 除了状态流转控制外,流程引擎还可以集成多种功能,如发送邮箱,飞书通知,条件判断,脚本处理等集成能力。 | 无 只支持状态的流转,没有其他功能提供 |
-
系统架构图
经过上面功能的拆分和选型,我们最终可以得到如下的系统架构图:
配置域:
为实现新工单接入,借助工作流引擎与 RDS 联合配置工单生命周期,抹平不同工单状态与流程流转差异。同时,对入参等基础信息校验、敏感信息加密,支持功能扩展配置。此外,系统将生成缓存快照,支持选择特定版本生效及版本回滚,全方位提升系统稳定性。
核心域&支撑域:
核心域聚焦维护工单中心生命周期,对外提供创单、推单等影响工单状态的关键接口。支撑域则不断拓展,持续丰富工单中心的通用能力,确保新接入的工单模型能迅速运用分单、协作、处置等通用功能,这将是我们后续迭代完善的重点方向。
业务域 :
业务域直接调用工单中心的原子能力,将业务工单生命周期管理委托给工单中心。工单中心借助 SPI/MQ,以同步或异步形式,将状态流转、任务分配等信息反馈给业务系统,业务系统仅做信息同步,不负责维护。不过,业务系统需自行搭建业务工单的账户体系并实施权限控制,工单中心不覆盖这一部分能力。
-
工单生命流程配置化的实现
不同的工单的状态机和工作流程不尽相同,工作流引擎作为工单的核心底层组件,承担了维护工单生命周期和状态的流转,同时提供流转过程中的处置、通知等能力的编排能力。
选型的 工作流引擎 需要支持以下的能力:(自研的成本不及项目预期,需调查司内已有产品来支持)
能力 | 例子 |
---|---|
支持发起rpc的调用 | 需要调用工单中心 |
任意状态关闭工单 | 撤销和退回会直接结束工单生命周期 |
需要支持存在环 | 比如工单审批拒绝后回到待处理状态 |
异步的方式触发状态流转 | 审批通过要触发工单状态以及行为的流转 |
支持自定义模版节点 | 以黑盒子的方式提供原子能力,不关系内部的调用和实现方式,可以进行通用能力的提效 |
支持分支流程 | 如果审批通过,工单状态调整为已完结,拒绝则重新流转为处理中 |
版本管理,泳道管理,灰度发布 | 基础的上线三板斧能力 |
支持失败手工重试 | 解决一段时间的故障导致工单流程永久卡住的问题 |
经过司内各种工作流引擎的调研,我们最终确定选择UG团队下的 aha的工作流引擎平台,它可以满足我们上面需要的所有诉求,并且还有着以下的优点:
- 高效的可视化编排、调试能力
- 流程协议标准化,可扩展能力强
- 支持力度强,已拉贷后专项群,有问题可以及时反映和提出解决方案
- 丰富的基础节点,可以覆盖大量场景
- 定位问题能力强,有很强的调用链路分析和日志定位能力
工作流执行demo
处置能力目前还没实现,处置将作为我们另一个提效课题,将集中多种处置手段的发起,幂等,重试等能力。
为避免工作流引擎上下游依赖过度复杂,我们指定工单中心作为对接工作流引擎的统一网关。工单系统借助 SPI/MQ,依据配置化规则调用下游各业务系统。实际调用链路中,虽存在业务系统与工单中心相互调用的情况,形成所谓的 “弱依赖” 循环,但仍应将工单中心视作底层工具系统。
工单中心回调业务系统存在两种方式,分别是SPI和MQ方式。
- SPI : 属于接口调用,适用于实时场景,在状态变更完成后需立即开展查询与展示操作。能够保障数据一致性,防止用户产生困扰或者重复操作的问题。
- MQ : 通过EventBus实现(在我们团队,内部的mq交互都是用eventbus组件实现,对比原生的rocketmq能有不错的接入提效)。一般用于对信息同步不敏感,只要保障数据最终一致性的场景。
效果图 :
功能 | 线上配置图 |
---|---|
通用 分单 流程(自动分单+通知) | |
运营工单部分状态流转配置图 | |
目前已配置的工单工作流 | |
已经沉淀的插件节点 |
-
模型设计
工单中心的表设计主要涵盖配置类和流水类,进一步可细分为支撑域和核心域。核心域表记录工单基础信息与生命周期流转,支撑域表服务于工单通用功能。
为支持多租户接入,每张表和接口均增加 biz_code
字段,以实现简单的逻辑数据隔离。
配置类: 因暂无前端接入,当前配置类表的数据写入与修改通过 DML 语句完成。配置表以工单类型(order_type
)为核心,调用工单中心的生成版本快照接口后,系统会依据当前数据库数据生成配置快照,并写入工单配置快照表。不过,只有将该版本号配置到 TCC 上,才会对 TCE 实例生效。借助 TCC 的能力,能以较低人力成本实现灰度发布、版本 回滚 及版本管理等功能。
四、问题出现以及解决方案
问题一:工作流异步唤醒导致的"同步延迟"问题
问题描述:
在 aha 里,异步等待节点借助 webhook 回调实现唤醒与推进。其底层逻辑是,一旦接收到 webhook 地址的回调调用,就会向 MQ 推送消息。执行服务消费该消息后,从 TOS 获取工作流执行和配置数据,进而唤醒并推进流程。不过,这会带来两个问题:
- 异步 回调导致数据同步问题,在 aha 中,借助 webhook 唤醒工作流采用异步底层实现。工单中心调用 webhook 后会迅速收到成功反馈,若此时立刻告知业务系统处理成功,业务系统前端会马上刷新页面并重新查询数据。然而,由于异步特性,工单状态等信息常常来不及同步到业务系统,进而产生 “同步延迟” 导致的数据不一致问题。
我们将异步推动工作流执行的行为定为Action,下面流程图中,蓝色的节点是通用节点,绿色是业务定制化节点。我们将通过工单中心将业务通用的能力以及状态流转编排至工作流中,以达到提效的目的。
红色节点就是异步导致数据同步的问题,黄色是优化后的链路,可以解决这个问题
解决方案:
解决方案也很巧妙,在配置工单行为时,会明确规定工单可从何种状态流转至其他状态。执行异步回调后,系统会进行 10 次循环(每次循环间隔 200 ms ),期间持续判断工单状态是否已转变为下一个预设状态。只有当工单状态成功变更后,才会将处理成功的结果反馈给业务系统。
同时,将该工单类型回调业务系统的方式设定为 SPI 方式。如此一来,当查询到工单中心的状态发生变更时,便能确保业务系统中的工单状态也已同步完成变更。
- 获取工作流数据过慢导致 mq 消费挤压, 异步 唤醒等待时间过长。 从 TOS 提取工作流执行过程数据耗时较长,致使在完成 webhook 回调后,工作流往往要 1 分钟后才会继续推进。这使得操作人员困惑不已,即便频繁刷新工单状态,也难以实现数据同步。约 1% 的异步流程会遭遇此类问题。
该问题我们反馈aha团队的同学后,他们也是很积极的配合我们进行方案设计,最终决定采用abase为主,tos为次的二级缓存方案,以解决异步唤醒过长的的问题。
问题二:业务系统和工单中心接口幂等能力和数据一致性建设
问题描述: 因为进行了系统的拆分,虽然在开发上进行了提效,但同时也会导致调用链路上变得更复杂,当前面临以下的链路场景:
- 工单所有的接口(从创单,分单,添加处理记录,跟进记录等等)都要实现幂等,保障接口存在幂等键,可重复调用,并且保障不会重复的写入数据。
- 工作流调用工单中心的接口都配置3次重试,如果都重试失败则进行告警,触发告警后在aha平台进行手动重试。
- 业务系统如果和工单中心存在冗余字段的存取,一律由工单中心通过SPI/EventBus进行数据回调后,从回调数据获取到相关数据后再更新,统一以工单中心数据为主,减少两个系统数据的差异性,同时,配置相关的核对任务,如果回调异常及时人工处理。
问题三:工作流升级只对增量数据生效
问题描述: 每个工单创建时会同步调用 aha 创建工作流,此时工单对应的工作流版本便固定下来,工单的整个生命周期会严格遵循该版本的工作流执行。若产品要增加工单状态或行为,这些改动仅对新的工作流版本生效,且只有新创建的工单才能应用这些变化。这是由于工作流难以在保留当前执行节点的同时完成自身升级。
这个问题目前没有比较好的解法,我们也和产品同步并暂时对这个场景妥协。对于aha的团队这类需求不是他们通用的功能,不太好帮我们进行实现,大家如果有比较好的实现想法可以在评论区评论喔!
(如果工作流引擎是自研的话,则可以考虑根据工单的诉求做定制化的设计,这个问题是使用基础组件的问题,而不是整体设计思路上存在的问题)
五、提效收益
技术收益
- 工单类需求研发效能的提升:预估提升70%以上,在贷后部门预估全年减少145的人日,理论上新的工单接入可以由19人日降低到5人日,譬如新增加一个工单的接入,后续工单的创建、申请人查询、审批人查询、审批&驳回、审批回调、处置、权限配置等这些行为将配置化实现 ,不会像以前一样以烟囱的方式建设。
- 工单中心接入配置标准文档 提供配置接入文档,要接入工单中心的业务只需要填写标准文档的信息后,提供给工单中心的同学即可帮忙实现配置和接入。工单接入研发效能的提升:预估提升70%以上。
- 运维效率的提升:预估提升90%以上,后面的监控、告警、数据分析等操作,我们只需要针对一套接口,分析一套模型即可。
- 学习&交接成本的降低:预估新同学可以节省50%以上的时间,去学习,了解工单的一些业务逻辑。
六、工单中心的未来蓝图
工单中心的建设核心思路是为了能够在相似的需求中带来更多的接入和运维的提效,解放人力,投入到更有价值的工作上。
当前我们主要从贷后的需求中发现工单,审批流,以及处置的能力是目前频繁会出现的需求,所以后面建设的重点是能够通过配置化降低审批流和处置能力的接入和维护成本,同时提供通用查询等通用能力避免各个系统重复的建设。
-
工单中心提供将多类通用能力通过工单模型关联的能力。
- 比如一个投诉工单,既能发起审批,也能发起处置,处置动作还会带来工单状态的流转等
-
工单中心不一定会提供核心能力,如果能通过配置化和统一模型带来对接入该功能提效也属于工单中心的范畴。
- 处置和审批其核心的能力运转不会建设在工单中心,而工单中心只是针对众多场景进行标准化接入,统一模型,沉淀通用接口。
人类掌握技能通常历经三个阶段,即认识、练习与自动化。而在系统发展,同样存在三个重要阶段,分别是硬编码、平台化以及智能化。工单中心的诞生,正是我们和系统在贷后发展进程中向前迈进的关键一步。