欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Netflix Conductor:微服务编排引擎

程序员文章站 2022-03-15 17:11:07
...

原文Netflix Conductor : A microservices orchestrator
作者:Viren Baraiya, Vikram Singh 翻译:Daisy 责编:仲培艺

Conductor是Netflix开源的一款微服务编排引擎,托管在GitHub上,使用Apache License 2.0许可。

Conductor是受到Netflix需要运行全球流媒体业务流程的启发,而构建的基于云的微服务编排引擎。

下面是一些流程案例:

  • 用来提取内容的Studio合作伙伴集成;
  • 基于IMF的内容提取;
  • 在Netflix中设置新标题流程;
  • 内容提取、编码和部署到CDN。

通常,其中的部分流程会专门使用pub/sub组合直接REST调用,并使用一个数据库来管理状态编排。但随着微服务数量和流程复杂性的增加,如果没有*协调器,那么获得这些分布式工作流的难度就会加大。

为什么不使用对等编排?

Pub/sub模型适用于一些简单的流程,对等编排很难进行扩展,并且很快就发现了很多问题:

  • 流程流被嵌套在多个应用代码内;
  • 通常,围绕输入/输出、SLAs等方面存在的紧耦合和假设,导致很难适应不断变化的需求;
  • 几乎没有办法系统地回答:“进程完成情况”。

Netflix将Conductor构建为一个编排引擎,可以满足以下需求,在应用中消除样板需求,并提供一个反应流:

  • 使用JSON DSL描述的工作流蓝图;
  • 跟踪和管理工作流;
  • 可以暂停、恢复和重新启动任务;
  • 可视化的用户流程界面;
  • 可根据需要,同步处理所有执行任务;
  • 处理工作流能够扩展到百万级别;
  • 可抽离客户端的排队服务;
  • 支持HTTP或其他传输方式,如gRPC。

Conductor已经在Netflix内部使用了近一年。Netflix称其已经帮助编排超过260万个流程,从简单的线性工作流程到运行多天的非常复杂的动态工作流程都有。

Netflix Conductor:微服务编排引擎

Conductor的架构图

该引擎的核心是状态机服务,也叫作决策器服务。当工作流事件(例如:任务完成、失败等),决策器将工作流蓝图与工作流的当前状态组合,识别下一个状态,并调度适当的任务或更新工作流的状态。

Decider使用分布式队列管理任务调度。Netflix一直在Dynomite上使用dyno-queues来管理分布式延迟队列。Dynomitedyno-queues都已经开源,这里是当初的开源文章

任务实现Worker

工作流任务由Worker实现,并通过API层进行通信。Worker通过编排引擎调用REST端点或者通过实现定期检查挂起的任务轮询循环来实现。轮询模型允许用户在Workers上处理背压,并在可能时,基于队列深度提供自动可伸缩性。Conductor提供API来检查每个Worker的工作负载大小,这样就可以自动伸缩Worker实例。

Netflix Conductor:微服务编排引擎

Worker与引擎直接通信图

  • API层——使用HTTP或gRPC轻松集成各个不同的客户端。
  • 存储——使用Dynomite作为存储方案,Elasticsearch作为索引流执行方案。存储API是可插拔的,可用于各种存储系统,包括传统的RDBMS或Apache Cassandra。

核心概念

工作流定义

工作流是使用基于JSON的DSL定义的,工作流蓝图定义了需要执行的一系列任务。要么是控制任务(例如:叉、连接、决策、子工作流等),要么是Worker任务。工作流还可以进行版本控制,可以灵活地进行升级和迁移。

工作流定义概述:

 {
  "name": "workflow_name",
  "description": "Description of workflow",
  "version": 1,
  "tasks": [
    {
      "name": "name_of_task",
      "taskReferenceName": "ref_name_unique_within_blueprint",
      "inputParameters": {
        "movieId": "${workflow.input.movieId}",
        "url": "${workflow.input.fileLocation}"
      },
      "type": "SIMPLE",
      ... (any other task specific parameters)
    },
    {}
    ...
  ],
  "outputParameters": {
    "encoded_url": "${encode.output.location}"
  }
}

任务定义

每个任务行为都由其任务定义模板控制。每个任务定义会提供任务参数,例如,超时,重试策略等。任务有两种,一个是Worker,运行在远端机器上的用户任务;一个System,运行在引擎的JVM上的任务。后者用来对Worker执行任务进行branch、fork、join。Worker任务通过HTTP或者gRPC(基于HTTP/2)和Conductor通信。

任务定义JSON代码片段:

 {
  "name": "encode_task",
  "retryCount": 3,
  "timeoutSeconds": 1200,
  "inputKeys": [
    "sourceRequestId",
    "qcElementType"
  ],
  "outputKeys": [
    "state",
    "skipped",
    "result"
  ],
  "timeoutPolicy": "TIME_OUT_WF",
  "retryLogic": "FIXED",
  "retryDelaySeconds": 600,
  "responseTimeoutSeconds": 3600
}

输入/输出

输入任务JSON代码片段:

{
      "name": "name_of_task",
      "taskReferenceName": "ref_name_unique_within_blueprint",
      "inputParameters": {
        "movieId": "${workflow.input.movieId}",
        "url": "${workflow.input.fileLocation}"
      },
      "type": "SIMPLE"
    }

未来计划

  • 支持AWS Lambda(或类似)函数作为无服务器任务;
  • 与容器编排框架进行更紧密的集成,这样工作实例就可以自动扩展;
  • 记录每个任务的执行数据;
  • 从UI上实现创建和管理工作流蓝图。