每天,世界各地的超级用户发起客户支持通过我们的票客户对平台。确保无缝的用户体验,这些票必须与代理用户的语言和说话谁已被训练来处理问题的类型和在那个国家,以及其他资格。
路由门票代理正确的技能随着乳房的增长已变得更加复杂。今天,我们支持许多类型的用户在不同的企业,每个都有自己的独特类型的问题和要求,这些票应优先和路由。在这些年的发展我们的匹配系统(以及支持这些用例人与自然语言处理简单的请求),但导致一个大的复杂系统,难以理解和难以更新而不破坏其他功能或引入新的错误。
2018年初,很明显,我们需要更换机票路由系统更灵活。我们需要开发一个解决方案,让我们更快地适应超级不断变化的需求,稳定规模。
在本文中,我们讨论我们的原因采用工作流编排票路由,我们面临的挑战在我们的迁移,我们开发的解决方案上节奏,超级的开源编配引擎。
早期的票在超级路由
支持门票超级有几个属性中使用路由过程直接流向特定支持代理训练来处理特定的客户支持用例。这些属性包括用户信息,如语言,国家,和票“类型”,例如,“Driver-partner问题支付”或“失去的物品。”门票也可能标有“用户组”如果用户属于人口需要专业支持,例如,“新driver-partners。“作为创建门票,他们根据这些属性和分类排队,直到一个合适的代理可以处理它们。
同样,支持代理商有一个显示的属性技能的训练来处理。例如,一个特工提供driver-partner支持在印度和训练提供额外帮助新的driver-partners可能有以下技能:
| 语言 | 印地语,英语 |
| 国家 | 印度 |
| 票类型 | Driver-Partner帐户、Driver-Partner支付Driver-Partner签约 |
| 用户段 | “新driver-partners” |
简单,票路由工作流必须考虑所有的属性的组合(类别),代理是训练来处理。从这些类别,它应该然后分配票等待时间最长的。
额外的优先级规则复杂化这个路由。例如,许多特工训练提供driver-partner支持,但是只有一个子集的代理收到额外的培训来支持新的driver-partners。最大化利用,这些特工应该分配票来自新driver-partners当一个是可用的。他们可能从其他driver-partners处理门票当没有“新driver-partner”门票,但“新driver-partner”票应优先。
挑战
在引擎盖下,超级的票路由系统使用多个属性除了上面所列的那些比赛门票代理。它还有许多优先级规则处理用户部分,安全门票,门票升级困难,等等。
这个路由逻辑始于简单,直接的代码,但它随着时间的推移变得更加复杂,以满足新的要求和原来的逻辑成为掩盖了这种复杂性。年的增长导致分散逻辑分散在许多类和源文件。的逻辑变得难以理解,难以修改。
这个分裂我们的代码更少的测试和监控更加困难。票核心路由逻辑分散在许多方法在几类。重要的步骤在该过程中,如确定类别一个代理可以处理,也分散在多个源文件中。当编写一个新功能,这个过程碎片很难发现和重用现有代码,导致代码重复。
虽然我们维护测试覆盖率高,我们的代码不再是结构化的方式有效地允许控制逻辑进行测试。我们的单元测试不能保证所有分散的逻辑正确操作或重复代码的行为相同。此外,这种分裂导致更少的有用的指标在RPC端点和系统性能,使它越来越难以深入和识别缺陷和其他问题的来源。这些因素最终导致不可靠和一致的经验为我们的客户提供支持。
这些问题也在很多方面影响了我们的日常开发。新开发人员需要更多的时间来上这个项目,和新功能设计和实现需要更长时间。即使是很小的变化会有副作用,打破了路由逻辑,bug引入时,他们很难识别和修复。这些因素结合在一起,使它很难跟上新的业务需求和优先级。
这些限制也为超级干扰我们的长期愿景的支持系统。作为超级扩展到新业务,它是至关重要的,我们支持基础设施能够处理门票形式除了随意组合和为所有企业提供support-as-a-service集中式工作流的一部分。
克服各种挑战,我们需要提供一个灵活的,但稳定的路由平台允许开发者在超级建立自己的路由规则在我们的系统,以支持新产品和模式。
路由是一个工作流
解决无数的问题提出了我们的遗产门票路由,我们决定设计工作流系统的票路由逻辑,使用节奏,我们的开源编配引擎,工作流引擎。节奏会使我们能够控制逻辑,模块化的业务逻辑,使路由更加灵活和易于理解。结合的节奏,模块化ticket路由工作流程,创建更好的代码结构和部署更加灵活的优先级逻辑使我们重新设计我们的路由系统工作流程。
总的来说,这些步骤使我们把客户对机票路由系统变成一个工作流,允许不仅提高了开发人员的经验和更灵活和持久的系统架构,而且一个更好、更可靠的客户体验。
利用节奏
节奏是分布式、可伸缩、耐用和高可用性,使它理想的适合我们的工作流程编排引擎。节奏模式的业务流程使用两个关键概念、工作流和活动。工作流协调逻辑,只负责策划活动的执行。活动是实现单个任务的业务逻辑。
节奏活动和工作流是托管在工作进程和执行。工人提供了足够的灵活性如何部署代码。每个工作流和活动可能是托管在自己的作为一种独特的工人,或一个工人可能会托管多个工作流和活动。这个特性是非常重要的,我们的目标是创建一个routing-as-a-platform编配引擎,因为这种类型的解决方案允许新的活动开发,部署,插入路由的工作流程,而不需要重新部署路由服务。
模块化票路由工作流
后进行一次彻底的审查我们的客户支持平台现有的路由代码,我们可以将核心路由逻辑变成一系列的离散任务。这些任务的逻辑链在一起成为新的路由工作流程,和每一个任务被编码为一个单独的模块,或“活动”在节奏方面,由工作流执行。
通过这种方式,我们的路由逻辑的复杂性减少到一个可管理的控制过程和一些简单的活动。
这些步骤是:
-
- 优先级分类
- 集团和代理的类别是训练有素的处理优先级。
- 获取候选人的票
- 检索所有可用的票代理高优先级队列的门票。
- 如果高优先级队列是空的,这一步是为下一个最高优先级组重复,直到找到一群非空。
- 分数候选人的票
- 一个分数分配给每一个候选人的票。在我们编排工作流初始版本的,这一点是完全基于年龄的票。
- 工作流体系结构允许新的评分模块很容易插入票路由工作流。这些评分模块可以链接在一起来支持更复杂的逻辑。
- 分配最高票
-
- 得分最高的的票是分配给代理。
-
- 优先级分类
虽然这个工作流支持所有的原系统的复杂性,更容易扫描和理解,因为控制逻辑已经清楚地分离和业务逻辑封装到少量的良好定义的模块。
重写路由逻辑作为工作流帮助我们改善代码的组织,独立的控制逻辑,并适当封装业务逻辑。更重要的是,采用工作流体系结构将迫使我们保持这个组织继续加强票路由。
更好的代码结构
提高我们的代码的组织也提高代码的可测试性。路由工作流中的主要步骤现在轮廓清晰和明确的合同,实施全面的单元测试。安排这些任务的控制逻辑是封装在一个单独的、容易测试工作流功能。我们选择的工作流引擎,节奏,还提供了一个优秀的测试框架,支持模拟活动,使其易于编写综合测试路由工作流。这使我们能够更改路由逻辑与平和的心态,我们不破坏其他用例。
在工作流活动收集有意义的指标,是一个有用的抽象。监测错误率和延迟从每个活动使我们能够迅速识别问题的根源。
由于这些改进,现在我们可以更改路由工作流比之前我们可以更快和更大的信心,问题可以发现得早。
灵活的优先级逻辑
我们重写了路由逻辑,取代了以前硬编码的优先级逻辑票得分步骤。这一步实际上包含多个活动,或评分模块,执行系列。评分模块的工作流程定义了一个简单的合同。每个必须采取一个代理描述和一个候选人的票列表与分数和返回一个列表的票更新分数。
评分模块旨在很小,单一责任,可组合的活动。例如,第一个进球模块运行在我们的工作流分配每张票一个初始分数等于它的年龄,以毫秒为单位。额外的评分模块可以影响路由的优先级,通过分数乘以一个促进因素,或通过添加一个具体的分数提高基于候选人的票的特点和代理。一连串的几个进球模块可以支持复杂的优先级用例没有复杂的代码,而单个模块仍小,易于理解。
此体系结构不需要像节奏的工作流引擎,但它确实需要采用工作流模式:使用离散任务,由一个单独的控制过程。利用节奏使它容易实现评分模块因为工作流引擎可以管理我们的业务流程的需求。此外,使用工作流引擎使这个架构更加灵活。评分模块可以添加、删除或重新定购商品容易现在控制平面与业务逻辑。作为一个未来的增强,我们计划将主动得分模块配置列表,允许无代码更新。一旦纳入评分模块工作流程,也可以更新和部署在隔离,无需更改代码或部署路由服务。
工作流模式转变
作为开发人员,我们习惯于将复杂的代码分解成小块使用函数和类。很容易天真地使用这种方法在编写工作流时,拉比特逻辑到活动或辅助函数,因为他们变得过于复杂或使用了不止一次。当我们尝试用更传统的方法在我们的发展过程中,我们发现,方法不够我们的需要。最终,迁移客户困扰票路由逻辑引入工作流所需的一种范式转移,我们考虑代码的方式。
传统的开发之间的关键区别和工作流模式是工作流强调任务之间的区别和控制逻辑来协调这些任务。在终止之前,我们的团队很少思考代码显式地在这些条款,并发现的区别并不像我们预期的那么简单。为了控制逻辑之间画一条线和任务,它是重要的识别原则来指导我们的设计。
我们的主要指导原则是我们的代码结构提高工作流的明确性。因为我们想让其他球队能够建立自己的路由逻辑,我们的控制逻辑将公众和客户对团队之外的是很重要的,开发人员可以很容易地扫描工作流和理解票路由过程。逻辑是必要的理解应该表达的工作流。复杂的细节,另一方面,可以模糊的核心逻辑。工作流变得更加清楚正确封装在活动的时候。下面,我们列出关键教训我们的经验在这个范式转变。
我们并没有使我们的逻辑太简单了…
我们早期的错误之一是试图简化控制逻辑。因为我们不熟悉控制逻辑与业务逻辑分开,我们最初的设计路由逻辑有一个欠发达的控制流和处理所有优先级通过评分模块。我们之前的代理与特殊的培训,帮助新driver-partners会由一个评分模块保证新driver-partner门票将得分高于其他代理的门票。
这种方法有一些问题。为了保护我们现有的逻辑,这样评分模块将需要确保匹配门票仍在列表的顶部,即使额外的评分模块组成。我们认为解决这个通过设置匹配的票的得分为零。然而,所有评分模块需要理解和尊重本公约。复杂评分模块开发人员写了合同,把负担评分模块。一个错误的逻辑可能mis-route门票的方式会影响我们的运营sla,更不用说导致低的用户体验
反思这个问题与清晰的原则,我们意识到我们是隐藏在路由过程中迈出的重要一步。我们有两种类型的优先级:过滤规则排序类别分为粗粒度组和评分规则,优先考虑这些组中的联系人。当我们重组工作流程,使过滤步骤明确,然而,工作流程和评分模块界面变得更加清晰。
…或太复杂
分离筛选和得分步骤让我们在正确的道路,但我们仍然找出最好的方法控制逻辑与业务逻辑分离。在我们的第二次尝试,矫枉过正的和过于逻辑到工作流。这一次,我们包括检查当前代理的性质和决定哪些优先群体应该在控制逻辑的一部分。
这个方法工作,当我们有六个总优先群体,控制逻辑仍相对容易理解。很快,然而,我们开始实施一项功能,需要两个新的优先群体具有独特的逻辑。直接添加这个工作流的控制逻辑难以阅读。
类别是如何按优先级分组的细节是一个复杂的细节模糊的重要逻辑工作流。节奏支持工作流管理的复杂性,许多选项包括工作流代码中完全支持面向对象编程。对于我们的用例,我们把优先级组逻辑从工作流和创建了一个新的活动来执行计算。工作流的意图变得容易理解当我们封装逻辑在一个明确的名字命名活动。此外,我们获得的好处节奏的耐用性和至多一次执行担保,计算。
总的来说,我们发现部门工作流和活动之间的逻辑需要平衡。投入太多的逻辑活动,和工作流变得太简单了。很难理解什么工作流,因为如此多的逻辑是隐藏在复杂的活动。另一方面,太多的逻辑是在工作流,真正的控制逻辑可以成为被不必要的复杂性。找到正确的平衡使我们的工作流容易阅读和维护。
支持工作流的低延迟
票路由过程是一个低延迟、同步过程执行在回应一个代理变得可用,请求一个新的机票。建模过程工作流创建了一些独特的挑战,因为工作流编排通常用于异步执行长期,latency-tolerant流程。
节奏通过执行工作流和活动之间使用一个工作队列任务列表。工作任务列表一旦工作流开始排队,每次执行从工作流传到另一个活动,反之亦然。这个设计支持耐用、高可用性和分布式工作流执行,但它也介绍活动转到另一种活动延迟的100毫秒。异步工作流为典型,这是完全可以接受的,但是我们需要更快的性能从路由流程因为它实时处理来自用户的请求。我们能够实现这一使用抑扬顿挫的当地活动的功能。
的当地的活动允许短暂的任务被调度和运行工作流的工作进程,而不是排队的工作任务列表。权衡是当地活动必须驻留在同一个流程工作流,我们失去了自由独立部署它们。
采用工作流架构我们的主要动机是为了提高代码的清晰和灵活性,不一定分布式执行。工作流设计呼吁公众通过评分模块的可扩展性。我们需要分布式的灵活性举办这些活动,但对于一切来说,使用本地活动是可以接受的。通过使用本地活动的核心步骤在我们的工作流程,我们可以几乎消除活动转到另一种活动延迟。今天,我们的路由工作流的平均性能与原路由代码及其p99性能实际上是提高了33%以上,从而改善用户体验的客户支持代理商和客户的喜爱。
我们承担一个小延迟成本通过节奏启动工作流。这个过程还在任务列表为异步队列工作分配工作流工人。我们测量端到端延时触发路由工作流过程中,一次又一次的工人执行工作流。我们发现触发工作流增加平均约20毫秒的延迟,但p99成本大约为160毫秒。这个延迟平衡的性能我们看到工作流。保理,在之后,microservices取决于机票路由系统看到类似的延迟从路由流程和旧的路由代码。
我们的路由工作流的未来
现在我们迁移工作流路由逻辑,我们计划使用工作流为基础为未来的增强。
可定制的路由逻辑
我们设计路由工作流是易于扩展。可以添加新的优先级规则通过编写一个新的评分模块。前进,我们计划建立在这种通过允许其他团队在超级提交新的评分模块有自己的路由逻辑。
修改功能的可插拔模块不是一个新奇的想法,可没有一个工作流体系结构。然而,采用工作流编排节奏使这更容易实现。其他球队可以在自己的代码库代码评分模块和主机活动甚至在工人在他们的服务serverless架构像超级的催化剂。
节奏的模型允许我们引用远程活动的名字从我们的路由工作流活动执行和可靠性提供了强有力的保证。这使它容易得分的路由工作流支持列表模块名称,可以动态地更新,插入新的路由逻辑。使用这个,我们设想路由工作流作为一个可扩展的平台提供可定制的路由,以满足超级的多样化需求。
DSL业务工作流描述语言:一个工作流
客户对团队合作与自动化平台团队开发工作流DSL称为业务工作流描述语言(BWDL)。而典型的节奏工作流编写代码,BWDL项目将支持基于json工作流定义。BWDL解释器将这些工作流定义JSON转换成节奏动态工作流。
这个项目的目的是支持工作流配置而不是代码。BWDL将有可能创建、更新和部署整个工作流没有代码更改或服务部署。
补充BWDL,客户对团队还在开发一种编排服务处理BWDL工作流的管理。它将提供存储、版本控制和执行等客户服务流程的工作流票路由,使开发人员能够专注于功能开发。
工作流管理界面
工作流BWDL将允许快速迭代,但只对技术用户舒适使用JSON DSL。一旦启动了,我们计划提供一个工作流编辑和管理UI与自动化平台团队通过持续合作。BWDL将作为基础,为JSON dsl很容易通过编程解析和生成。
这个UI允许非技术用户创建和修改工作流通过安排组件(活动)拖放界面,连接彼此用一组简单的条件。
通过这些更新和其他人来说,我们希望提供一个路由平台与客户对代理可以动态更新和配置按需路由逻辑,从而改善经验在客户支持经验。
感兴趣的设计编排工作流在规模或导致节奏和其他超级开源技术?申请一个角色我们的团队。






