任务流引擎简介
任务流简介 任务比如 k8s 概念中的 job,一般指的是短期的会结束的一个离线任务,而人物流就是将一组任务组织起来的流程。比如下面的这个流程。
任务流中除了支持简单的串行处理之外,通常还会支持 并发,条件,skip 等影响执行流程的功能 任务流一般是 DAG,即不支持有环操作,在大部分场合这也能满足绝大部分需求了 每个 Step 通常除了 action 之外,通常还会有输入输出,这种输入输出 可能是一段数据,也可能是一个打包好的文件,甚至一个 测试生成的 html 页面等等 任务流的启动 可以是手动触发,也可能是各种事件处罚,比如一个 github merge事件。也可能是 cron 处罚,即周期执行。 任务流的例子 Jenkins 最早接触任务流工具应该是在 jenkins, 实际上 CI/CD 也是任务流最常见的场景之一,不过 jenkins 并不局限于 ci/cd (大部分 ci/cd 工具也是这种设计,采用 通用工作流 + 业务插件的形式支持具体的业务)
jenkins 的任务流有几种表达方式
在页面上配置 使用 JenkinsFile 表达,而 JenkinsFile 表达也有两种形式,一种成为 描述性语法:Declarative Pipeline,语法比较简单易用,另一种为脚本语法 Scripted Pipeline,内部使用 Groovy 语言进行编辑,有一定的上手门槛,但是非常灵活,功能强大
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
//
}
}
stage('Test') {
steps {
//
}
}
stage('Deploy') {
steps {
//
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Build') {
//
}
stage('Test') {
//
}
stage('Deploy') {
//
}
}
事实上 Jenkins 还是 CI/CD 领域应用最多的任务流工具,其强大的社区,各种强大的插件体系,使得他在十多年后依然不过时( Jenkins 的前身 Hudson 是在 2004 发布的),最近几年 Jenkins 又支持了 容器,K8S 的支持,使得他依然是这个领域最好用的工具。
在这个领域的的工具还有很多,比如在 github 上就内置了官方的 github actions工具,circle ci 等等,在这个 容器盛行的时代,构建这样一个 CI/CD 工具远没有当年构建 Jenkins 的门槛那么高了,相关的一些基于容器、K8S 主打灵活,高性能的开源工作流工具也层出不穷。
Drone drone 是容器时代的任务流工具中最有代表性的开源工具之一,他的任务流的表达方式和其他同时期的产品非常类型,都是 yaml 的形式。顺应时代,drone 支持在 docker, kubernetes 或者直接利用 ssh 方式运行,不过我们这里只关注 docker 和 kubernetes 类型。
每一个 Step其实都是一个容器,在 kubernetes 上则是一个 pod,drone 的插件体系也是基于此构建。所谓插件 就是一个定制的镜像,接受一些参数(从环境变量)进行操作,输出参数,这种设计使得定制、增加插件的成本非常低,这可能也是 drone 活跃的重要原因之一(其实这种做法现在已经非常常见了) Step 之间使用 环境变量传递元数据 Step 通过内置的一个内存消息队列进行驱动,不依赖外部组件
name: default
kind: pipeline
type: docker
steps:
- name: backend
image: golang
commands:
- go get
- go build
- go test
- name: frontend
image: node:6
commands:
- npm install
- npm test
- name: publish
image: plugins/docker
settings:
repo: octocat/hello-world
tags: [ 1, 1.1, latest ]
registry: index.docker.io
- name: notify
image: plugins/slack
settings:
channel: developers
username: drone
argo 和 tekton argo 和 Tekton 都是 Kubernetes 原生的工具,两者的实现上也很类似。
argo argo 的也是用 yaml 描述工作流,除了传统的 dag 模式,argo 也支持 workflow 模式。相比而言,dag 模式一般比较简单,大部分 ci/cd 场合也比较够用,实现的事情用下面的 几行代码 就可以描述
start
for node in nodes:
if all(node's dependency is done):
do(node)
done
而 workflow 模式则是一个状态机, workflow 模式的实现更为复杂,也更灵活。用这种模式可以实现有环的任务,比如 执行一个任务,直到某条件满足。
if node's State is not start:
start(node)
if node's State is not done:
do(node's Next)
下面是 argo workflow 的一个具体例子
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-
spec:
entrypoint: hello-hello-hello
# This spec contains two templates: hello-hello-hello and whalesay
templates:
- name: hello-hello-hello
# Instead of just running a container
# This template has a sequence of steps
steps:
- - name: hello1 # hello1 is run before the following steps
template: whalesay
arguments:
parameters:
- name: message
value: "hello1"
- - name: hello2a # double dash => run after previous step
template: whalesay
arguments:
parameters:
- name: message
value: "hello2a"
- name: hello2b # single dash => run in parallel with previous step
template: whalesay
arguments:
parameters:
- name: message
value: "hello2b"
# This is the same template as from the previous example
- name: whalesay
inputs:
parameters:
- name: message
container:
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
argo 的 workflow 里面也是类似 drone,step 由容器实现,并且做得更为直接。
在 argo 上,kubeflow 社区就实现了针对机器学习领域的 pipeline 工具 KubeFlow-Pipeline
更多关于 argo 的原理可以参考这篇文章
tekton
tekton 来自Knative的build模块 做的事情和 argo 也大同小异,他扩展比较灵活,可以用来快速定制实现所需功能。tekton 的描述语法例子如下
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: echo-hello-world
spec:
steps:
- name: echo
image: ubuntu
command:
- echo
args:
- "Hello World"
除了 task,tekton 还定义了 如 PipelineResource, TaskRun 等多种资源,描述性语法。目前由于实现原理的限制(通过扩展 kubernetes api resources,watch 资源变化实现,类似 operator),决定了 argo 和 tekton 都不能水平扩容,这一点限制了系统的 scale 能力,吞吐量有一定限制,但是对于 ci/cd 的场景,应该是很够用了。
关于 tekton 的特点,这篇文章 做了详细的对比
brigade brigade 也是一个基于 kubernetes 的 pipeline 工具,作者是大名鼎鼎的 helm(公司被微软收购) 的作者,这个工具值得一提的原因是其设计非常有趣,他的语法不使用常见的 yaml 描述,而是采用 js 的方式描述。比如下面这个例子。
const { events, Job } = require("brigadier");
events.on("simpleevent", (e, p) => { // handler for a SimpleEvent
var echo = new Job("echosimpleevent", "alpine:3.8");
echo.tasks = [
"echo Project " + p.name,
"echo event type: $EVENT_TYPE",
"echo payload " + JSON.stringify(e.payload)
];
echo.env = {
"EVENT_TYPE": e.type
};
echo.run();
});```
由于 kubernetes 对于部署和标准化环境的控制,以及 kubenetes 提供基础设施的强大能力,使得在 kubernetes 上实现类似的工具变得门槛很低,笔者也在早年也做过类似的 [玩具项目](https://github.com/arlert/kubepipe),
看一下他的语法,是不是更 tekton/argo 有些相似呢。
```kubernetes
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
restartPolicy: Never
containers:
- name: c
image: alpine
command: ["sh", "-c", "echo running pod1"]
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
restartPolicy: Never
containers:
- name: c
image: alpine
command: ["sh", "-c", "echo running pod2"]
---
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
restartPolicy: Never
containers:
- name: c
image: alpine
command: ["sh", "-c", "echo running pod3"]
---
apiVersion: v1
kind: Pipe
metadata:
name: pipe
spec:
stages:
- name: stage1
jobs:
- pod1
- name: stage2
jobs:
- pod2
- name: stage3
jobs:
- pod3
总结
上面讲的工具大部分是 pipeline工具,使用的场景也在 ci/cd 上(尽管大部分工具实际也可以用来干别的事情),这种工具非常多,各大云厂商也提供了各种 workflow/pipeline 引擎比如 aws的 Simple WorkFlow,AWS Step Functions,Azure的 Pipeline 服务,ML Pipeline。
成熟的任务流引擎,应该有如下4层架构(图和分层方式来自 https://juejin.im/post/5ee2f6ece51d457848686ef8)
第一层:用户交互层。如:模板语法规则,Console界面等 第二层:API持久化层。如:模板记录,历史执行记录等 第三层:引擎实例层。如:能否水平扩容,流程是否有优先级等 第四层:驱动层。如:一个步骤能干什么活。跑一个容器还是跑一个Spark任务。 选择或者实现一个任务流引擎的时候需要从这四方面判断它的优劣,比如大部分开源工具 在第一层和第二层的支持较好,但是 argo 和 tekton 不能水平扩容,第三层的实现有些不足。同时 这两个工具又局限于 kubernetes 语境,其第四层的设计也比较局限。不过第四层的设计一般取决于具体的场景,比如在云上,云厂商首先会支持一个通用 serveless 函数,在机器学习平台,会支持运行一个 spark 任务等等。
由于任务流工具应用的广阔场景,CNCF 也忍不住指定了基于云原生的 workflow 标准。
看下 cncf 的 spec 可以看出 cncf的标准指定得还是比较复杂, 支持 subflow,foreach,delay, paralle 等特性,而云产商如 aws 实现的类似产品 spec 则更为简单. 目前还没有知名的 cncf 标准的 workflow 实现出现,不过可以预期,以 cncf 的影响力,类似的开源项目很快就会出现,这个领域还有很多机会。
有限状态机 产品经理要知道的知识点——有限状态机 状态机工作流 状态机工作流.实列.报销审批流程(一) 如何实现一个有限状态自动机[状态机] 工作流引擎在vivo营销自动化中的应用实践 | 引擎篇03 Spring StateMachine(1) 二级审批流程 Workflow Engine 工作流引擎 —— 什么是状态机(Finite-state machine)? 状态模式:游戏、工作流引擎中常用的状态机是如何实现的? 一种多状态机管理引擎的配置管理方法
Java是一种广泛应用于企业级应用开发的编程语言,而审批流程设计则是指在企业中对各种业务流程进行管理和控制的一种方法。在Java中,我们可以利用各种技术和框架来设计和实现审批流程,以提高工作效率和管理水平。
审批流程设计的目的是为了确保企业中的各种业务流程能够按照规定的步骤和流程进行,并且能够及时地获得上级的批准和授权。在Java中,我们可以使用以下几种方法来设计和实现审批流程:
-
使用工作流引擎:Java中有很多成熟的工作流引擎,如Activiti、JBPM等,可以帮助我们快速搭建和管理审批流程。这些工作流引擎提供了一套完整的工作流程设计和管理工具,可以方便地定义流程节点、流程变量、流程规则等,并且可以通过图形化界面进行配置和管理。
-
使用状态机:状态机是一种用于描述对象状态和状态转换的模型,可以用来设计和实现审批流程。在Java中,我们可以使用开源的状态机框架,如Spring Statemachine、EasyFlow等,来定义和管理审批流程的各个状态和状态转换规则。通过状态机框架,我们可以方便地定义和管理审批流程的状态和状态转换,并且可以在代码中灵活地控制流程的执行。
-
使用规则引擎:规则引擎是一种用于管理和执行规则的引擎,可以用来设计和实现审批流程中的各种规则和条件。在Java中,我们可以使用开源的规则引擎,如Drools、Easy Rules等,来定义和管理审批流程中的规则和条件。通过规则引擎,我们可以方便地定义和管理审批流程中的各种规则,并且可以在运行时动态地执行和调整规则。
-
使用数据库和消息队列:在Java中,我们可以使用数据库和消息队列来设计和实现审批流程。通过数据库,我们可以存储和管理审批流程的各种数据和状态,并且可以通过SQL语句进行查询和更新。通过消息队列,我们可以实现审批流程中的异步通信和消息传递,以提高系统的并发处理能力和可靠性。
Java审批流程设计可以通过工作流引擎、状态机、规则引擎、数据库和消息队列等技术和方法来实现。这些方法各有优劣,可以根据具体的业务需求和系统要求来选择和应用。通过合理的审批流程设计,可以提高企业的工作效率和管理水平,实现业务流程的自动化和标准化。