pipeline 分布式任务调度器

目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器。

可以将要执行的任务打包为docker镜像,或者选择已有镜像,自定义脚本程序,通过pipeline框架来实现调度。

开源地址: https://github.com/jadepeng/docker-pipeline

架构

  • pipeline master 中心节点,管理和调度任务
  • pipeline agent 执行任务的节点,接收到任务后,调用docker执行pipeline任务

功能特性 && TODO List

  • [x] 分布式框架,高可用,服务注册与状态维护
  • [x] Agent执行任务
  • [x] rolling日志接口
  • [x] 运行老版本pipeline任务
  • [x] 支持定时执行任务(固定周期和cron表达式)
  • [ ] 快速创建任务,支持python、node等脚本程序直接执行
    • [x] python、java等基础镜像
    • [x] 快速docker镜像任务API
    • [ ] 快速创建脚本任务
  • [ ] 根据资源配额(内存、CPU)调度任务, 运行任务需要指定资源配额
  • [ ] agent 增加label标识,调度时可以调度到指定label的agent,比如gpu=true
  • [ ] 增加任务管理web, 管理提交任务、查询运行日志等
    • [x] 复用腾讯bk-job 网页
    • [ ] 修改bk-job前端,适配pipeline

进展

2021.07.31

  • 支持定时执行任务(固定周期和cron表达式)
  • 增加分布式mongodb锁,多master时,同时只能有一个master schedule任务

2021.07.28

  • 新增运行老版本pipeline任务能力
  • 增加日志接口

2021.07.27

  • 引入bk-job的ui,待修改

2021.07.21

  • Master 调用 agent执行任务
  • agnet 启动docker执行任务

2021.07.19

  • 基于jhipster搭建框架
  • 分布式实现

数据结构

一个pipeline 任务:

  • 支持多个pipelineTask
  • 一个pipelineTask 包含多个Step
  1. @Data
  2. public class Pipeline {
  3. @Id
  4. private String id;
  5. private String name;
  6. @JSONField(name = "pipeline")
  7. private List<PipelineTask> pipelineTasks = new ArrayList<>();
  8. private List<Network> networks = Lists.newArrayList(new Network());
  9. private List<Volume> volumes = Lists.newArrayList(new Volume());
  10. private String startNode;
  11. /**
  12. * 调度类型:
  13. * 1) CRON, 设置cronExpression
  14. * 2) FIX_RATE, 设置fixRateInSeconds
  15. */
  16. private ScheduleType scheduleType = ScheduleType.NONE;
  17. /**
  18. * CRON表达式,在scheduleType=CRON 时生效
  19. */
  20. private String cronExpression;
  21. /**
  22. * 固定周期运行,比如每隔多少s,在scheduleType=FIX_RATE 时生效
  23. */
  24. private int fixRateInSeconds;
  25. /**
  26. * 是否需要调度,为true时,才调度
  27. */
  28. @Indexed
  29. private boolean enableTrigger;
  30. private long lastTriggerTime;
  31. @Indexed
  32. private long nextTriggerTime;
  33. /**
  34. * 执行超时时间
  35. */
  36. private int executorTimeout;
  37. /**
  38. * 重试次数
  39. */
  40. private int executorFailRetryCount;
  41. /**
  42. * 内存限制
  43. */
  44. private String memory;
  45. /**
  46. * CPU 限制
  47. */
  48. private String cpu;
  49. @Data
  50. @Builder
  51. public static class PipelineTask {
  52. /**
  53. * 名称
  54. */
  55. String name;
  56. /**
  57. * 别名
  58. */
  59. String alias;
  60. /**
  61. * 依赖的pipelines,必须依赖的执行完成才能运行该PipelineTask
  62. */
  63. List<String> dependencies;
  64. /**
  65. * 任务步骤,顺序执行
  66. */
  67. List<Step> steps;
  68. }
  69. @Data
  70. public static class Network {
  71. String name = "pipeline_default";
  72. String driver = "bridge";
  73. }
  74. @Data
  75. public static class Volume {
  76. String name = "pipeline_default";
  77. String driver = "local";
  78. }
  79. @Data
  80. public static class StepNetwork {
  81. private String name;
  82. private List<String> aliases = Lists.newArrayList("default");
  83. public StepNetwork(String name) {
  84. this.name = name;
  85. }
  86. }
  87. }

举例:

  1. {
  2. "_id" : "29103d5e4a77409b9f6050eea8110bb3",
  3. "name" : "docker image pipeline",
  4. "pipelineTasks" : [
  5. {
  6. "name" : "docker image pipeline",
  7. "steps" : [
  8. {
  9. "name" : "defaultJob",
  10. "image" : "java-pipeline:1.0.1",
  11. "workingDir" : "/workspace",
  12. "environment" : {},
  13. "networks" : [
  14. {
  15. "name" : "pipeline_default",
  16. "aliases" : [
  17. "default"
  18. ]
  19. }
  20. ],
  21. "onSuccess" : false,
  22. "authConfig" : {}
  23. }
  24. ]
  25. }
  26. ],
  27. "networks" : [
  28. {
  29. "name" : "pipeline_default",
  30. "driver" : "bridge"
  31. }
  32. ],
  33. "volumes" : [
  34. {
  35. "name" : "pipeline_default",
  36. "driver" : "local"
  37. }
  38. ],
  39. "cronExpression" : "0 0 * * * ?",
  40. "fixRateInSeconds" : 0,
  41. "scheduleType" : "CRON",
  42. "enableTrigger" : true,
  43. "lastTriggerTime" : 1627744509047,
  44. "nextTriggerTime" : 1627747200000,
  45. "executorTimeout" : 0,
  46. "executorFailRetryCount" : 0,
  47. "isAvailable" : 1,
  48. "runningPipelines" : [],
  49. "finishedPipeliens" : [],
  50. "created_by" : "admin",
  51. "created_date" : "2021-07-20T04:33:16.477Z",
  52. "last_modified_by" : "system",
  53. "last_modified_date" : "2021-07-31T15:15:09.048Z"
  54. }

使用说明

安装部署

编译

使用mvn编译

  1. mvn package -DskipTests

部署master

根据需要,修改master的prod配置文件application-prod.yml

包含kafka配置,server端口,mongodb地址,jwt secret配置。

mongodb 会自动新建collection和初始化数据,无需手动导入数据。

  1. kafka:
  2. producer:
  3. bootstrap-servers: 127.0.0.1:9092
  4. retries: 3
  5. batch-size: 2000
  6. buffer-memory: 33554432
  7. consumer:
  8. group-id: consumer-pipeline
  9. auto-offset-reset: earliest
  10. enable-auto-commit: true
  11. bootstrap-servers: 172.31.161.38:9092
  12. server:
  13. port: 8080
  14. spring:
  15. data:
  16. mongodb:
  17. uri: mongodb://127.0.0.1:28017
  18. database: pipeline
  19. jhipster:
  20. security:
  21. authentication:
  22. jwt:
  23. base64-secret:

注意master的jwt secret需要和agent的保持一致。

配置好后,启动:

  1. nohup java -jar pipeline-master-$version.jar --spring.profiles.active=prod &

可以将application-prod.yml放在和jar包同一目录。

部署agent

根据需要,修改master的prod配置文件application-prod.yml

包含:

  • eureka的defaultZone,配置master的地址
  • 端口
  • docker地址
    • docker-tls-verify: 是否启动tls验证
    • docker-cert-path:启动tls验证的ca证书
    • pipeline-log-path: 运行日志存储路径

  1. eureka:
  2. instance:
  3. prefer-ip-address: true
  4. client:
  5. service-url:
  6. defaultZone: http://admin:${jhipster.registry.password}@127.0.0.1:8080/eureka/
  7. server:
  8. port: 8081
  9. application:
  10. docker-server:
  11. docker-tls-verify: true
  12. docker-cert-path: /mnt/parastor/pipeline/ca/
  13. pipeline-log-path: /mnt/parastor/pipeline/logs/
  14. jhipster:
  15. security:
  16. authentication:
  17. jwt:
  18. base64-secret:

执行老版本任务

  1. POST /api/pipelines/exec-old
  2. Body
  1. {
  2. "networks":[
  3. {
  4. "driver":"bridge",
  5. "name":"pipeline_network_3eac4b36209a41e58a5f22dd403fee50"
  6. }
  7. ],
  8. "pipeline":[
  9. {
  10. "alias":"Word",
  11. "dependencies":[],
  12. "name":"pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1",
  13. "nextPipelines":[],
  14. "steps":[
  15. {
  16. "alias":"Word",
  17. "auth_config":{},
  18. "command":[
  19. "echo $CI_SCRIPT | base64 -d | /bin/bash -e"
  20. ],
  21. "entrypoint":[
  22. "/bin/bash",
  23. "-c"
  24. ],
  25. "environment":{
  26. "CI_SCRIPT":"CmlmIFsgLW4gIiRDSV9ORVRSQ19NQUNISU5FIiBdOyB0aGVuCmNhdCA8PEVPRiA+ICRIT01FLy5uZXRyYwptYWNoaW5lICRDSV9ORVRSQ19NQUNISU5FCmxvZ2luICRDSV9ORVRSQ19VU0VSTkFNRQpwYXNzd29yZCAkQ0lfTkVUUkNfUEFTU1dPUkQKRU9GCmNobW9kIDA2MDAgJEhPTUUvLm5ldHJjCmZpCnVuc2V0IENJX05FVFJDX1VTRVJOQU1FCnVuc2V0IENJX05FVFJDX1BBU1NXT1JECnVuc2V0IENJX1NDUklQVAplY2hvICsgamF2YSAtY3AgL2RhdGF2b2x1bWUvcGRmX3RvX3dvcmQvcGRmYm94X3V0aWwtMS4wLVNOQVBTSE9ULmphciBjb20uaWZseXRlay5pbmRleGVyLlJ1bm5lciAtLWlucHV0UERGIC9kYXRhdm9sdW1lL2V4dHJhY3QvZjkyYzJhNzViYWU4NGJiMDg4MzIwNWRiM2YyZGFlNzkvcGRmL2VjNWMwYjk0M2QwYjRmNDI5MzcyMmE1ZGRjNjFlNjZkL0hTNy5wZGYgLS1vdXRwdXRXb3JkIC9kYXRhdm9sdW1lL2V4dHJhY3QvZjkyYzJhNzViYWU4NGJiMDg4MzIwNWRiM2YyZGFlNzkvcGRmVG9Xb3JkL2VjNWMwYjk0M2QwYjRmNDI5MzcyMmE1ZGRjNjFlNjZkLyAtLXNjaGVtYUlucHV0UGF0aCAvZGF0YXZvbHVtZS9leHRyYWN0L2ticWEvZjkyYzJhNzViYWU4NGJiMDg4MzIwNWRiM2YyZGFlNzkgLS1lbnRpdHlJbmRleFBhdGggL2RhdGF2b2x1bWUvZXh0cmFjdC9mOTJjMmE3NWJhZTg0YmIwODgzMjA1ZGIzZjJkYWU3OS9wZGZUb1dvcmQvZW50aXR5IC0tZmllbGRJbmRleFBhdGggL2RhdGF2b2x1bWUvZXh0cmFjdC9mOTJjMmE3NWJhZTg0YmIwODgzMjA1ZGIzZjJkYWU3OS9wZGZUb1dvcmQvZmllbGQgLS10eXBlIGx1Y2VuZSAtLW91dHB1dCAvZGF0YXZvbHVtZS9leHRyYWN0L2Y5MmMyYTc1YmFlODRiYjA4ODMyMDVkYjNmMmRhZTc5L3BkZlRvV29yZC9lYzVjMGI5NDNkMGI0ZjQyOTM3MjJhNWRkYzYxZTY2ZC9lbnRpdHlJbmZvLnR4dApqYXZhIC1jcCAvZGF0YXZvbHVtZS9wZGZfdG9fd29yZC9wZGZib3hfdXRpbC0xLjAtU05BUFNIT1QuamFyIGNvbS5pZmx5dGVrLmluZGV4ZXIuUnVubmVyIC0taW5wdXRQREYgL2RhdGF2b2x1bWUvZXh0cmFjdC9mOTJjMmE3NWJhZTg0YmIwODgzMjA1ZGIzZjJkYWU3OS9wZGYvZWM1YzBiOTQzZDBiNGY0MjkzNzIyYTVkZGM2MWU2NmQvSFM3LnBkZiAtLW91dHB1dFdvcmQgL2RhdGF2b2x1bWUvZXh0cmFjdC9mOTJjMmE3NWJhZTg0YmIwODgzMjA1ZGIzZjJkYWU3OS9wZGZUb1dvcmQvZWM1YzBiOTQzZDBiNGY0MjkzNzIyYTVkZGM2MWU2NmQvIC0tc2NoZW1hSW5wdXRQYXRoIC9kYXRhdm9sdW1lL2V4dHJhY3Qva2JxYS9mOTJjMmE3NWJhZTg0YmIwODgzMjA1ZGIzZjJkYWU3OSAtLWVudGl0eUluZGV4UGF0aCAvZGF0YXZvbHVtZS9leHRyYWN0L2Y5MmMyYTc1YmFlODRiYjA4ODMyMDVkYjNmMmRhZTc5L3BkZlRvV29yZC9lbnRpdHkgLS1maWVsZEluZGV4UGF0aCAvZGF0YXZvbHVtZS9leHRyYWN0L2Y5MmMyYTc1YmFlODRiYjA4ODMyMDVkYjNmMmRhZTc5L3BkZlRvV29yZC9maWVsZCAtLXR5cGUgbHVjZW5lIC0tb3V0cHV0IC9kYXRhdm9sdW1lL2V4dHJhY3QvZjkyYzJhNzViYWU4NGJiMDg4MzIwNWRiM2YyZGFlNzkvcGRmVG9Xb3JkL2VjNWMwYjk0M2QwYjRmNDI5MzcyMmE1ZGRjNjFlNjZkL2VudGl0eUluZm8udHh0Cg=="
  27. },
  28. "image":"registry.iflyresearch.com/aimind/java:v1.0.0",
  29. "name":"pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1",
  30. "networks":[
  31. {
  32. "aliases":[
  33. "default"
  34. ],
  35. "name":"pipeline_network_3eac4b36209a41e58a5f22dd403fee50"
  36. }
  37. ],
  38. "on_success":true,
  39. "volumes":[
  40. "pipeline_default:/aimind",
  41. "/mnt/parastor/aimind/shared/:/share",
  42. "/mnt/parastor/aimind/pipeline-jobs/2021/07/26/3eac4b36209a41e58a5f22dd403fee50:/workspace",
  43. "/mnt/parastor/aimind/datavolumes/carmaster:/datavolume"
  44. ],
  45. "working_dir":"/workspace"
  46. }
  47. ]
  48. }
  49. ],
  50. "volumes":[
  51. {
  52. "driver":"local",
  53. "name":"pipeline_default"
  54. }
  55. ]
  56. }

成功返回:

  1. {
  2. "retcode": "000000",
  3. "desc": "成功",
  4. "data": {
  5. "id": "8137f344-f52d-4595-bdbb-425363847b61",
  6. }
  7. }

可根据id获取日志。

获取job执行日志

  1. GET /api/pipelines/jobLog/{jobid}/

结果:

  1. {
  2. "retcode": "000000",
  3. "desc": "成功",
  4. "data": {
  5. "currentTask": null,
  6. "logs": [
  7. {
  8. "id": "e76a686f68b64c0783b7721b058be137",
  9. "jobId": "8137f344-f52d-4595-bdbb-425363847b61",
  10. "status": "FINISHED",
  11. "taskName": "pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1",
  12. "exitedValue": 0,
  13. "logs": [
  14. "proc \"pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1\" started",
  15. "pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1:+ java -cp /datavolume/pdf_to_word/pdfbox_util-1.0-SNAPSHOT.jar com.iflytek.indexer.Runner --inputPDF /datavolume/extract/f92c2a75bae84bb0883205db3f2dae79/pdf/ec5c0b943d0b4f4293722a5ddc61e66d/HS7.pdf --outputWord /datavolume/extract/f92c2a75bae84bb0883205db3f2dae79/pdfToWord/ec5c0b943d0b4f4293722a5ddc61e66d/ --schemaInputPath /datavolume/extract/kbqa/f92c2a75bae84bb0883205db3f2dae79 --entityIndexPath /datavolume/extract/f92c2a75bae84bb0883205db3f2dae79/pdfToWord/entity --fieldIndexPath /datavolume/extract/f92c2a75bae84bb0883205db3f2dae79/pdfToWord/field --type lucene --output /datavolume/extract/f92c2a75bae84bb0883205db3f2dae79/pdfToWord/ec5c0b943d0b4f4293722a5ddc61e66d/entityInfo.txt",
  16. "proc \"pipeline_task_3eac4b36209a41e58a5f22dd403fee50_1\" exited with status 0"
  17. ]
  18. }
  19. ],
  20. "exitedValue": 0,
  21. "status": "FINISHED",
  22. "pipelineJobSt": 1627477250599,
  23. "pipelineJobFt": 1627477274299
  24. }
  25. }

周期任务

如果pipelien需要周期执行,需要配置enableTrigger为true,同时设置按照CRON或者FIX_RATE` 运行:

  • FIX_RATE: 固定周期,通过fixRateInSeconds配置周期运行时间

示例:每360秒运行一次:

  1. {
  2. // pipeline ...
  3. "pipelineTasks" : [ ],
  4. "fixRateInSeconds" : 360,
  5. "scheduleType" : "FIX_RATE",
  6. "enableTrigger" : true
  7. }
  • CRON: 按照CRON表达式周期执行,通过cronExpression配置.

示例:每小时开始的时候运行一次:

  1. {
  2. // pipeline ...
  3. "pipelineTasks" : [ ],
  4. "cronExpression" : "0 0 * * * ?",
  5. "scheduleType" : "CRON",
  6. "enableTrigger" : true
  7. }

更多待解锁

开源基于docker的任务调度器pipeline,比`quartzs` 更强大的分布式任务调度器的更多相关文章

  1. 【struts2】自定义更强大的logger拦截器

    Struts2自带的logger拦截器只是打印出了Action所对应的URL以及执行的方法名称,这对实际开发来说是肯定不够的.实际开发中为了调试方便,要记录的信息比较多,通常需要把这次请求相关的几乎所 ...

  2. 十大基于Docker的开发工具

    http://www.infoq.com/cn/news/2014/08/top-10-open-source-docker FlynnFlynn是一个使用Go语言编写的开源PaaS平台,Flynn使 ...

  3. 分布式任务调度系统:xxl-job

    任务调度,通俗来说实际上就是"定时任务",分布式任务调度系统,翻译一下就是"分布式环境下定时任务系统". xxl-job一个分布式任务调度平台,其核心设计目标是 ...

  4. [开源]基于ffmpeg和libvlc的视频剪辑、播放器

    [开源]基于ffmpeg和libvlc的视频剪辑.播放器 以前研究的时候,写过一个简单的基于VLC的视频播放器.后来因为各种项目,有时为了方便测试,等各种原因,陆续加了一些功能,现在集成了视频播放.视 ...

  5. 基于docker搭建开源扫描器——伏羲

    基于docker搭建开源扫描器——伏羲 1.简介 项目地址 伏羲是一款开源的安全检测工具,适用于中小型企业对企业内部进行安全检测和资产统计. 功能一览: 基于插件的漏洞扫描功能(类似于巡风) 漏洞管理 ...

  6. 分布式任务调度系统xxl-job搭建(基于docker)

    一.简介 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用. 更多介绍,请访问官网: http://w ...

  7. 远程访问禅道开源版数据库(基于docker)

    navicat访问基于docker搭建的禅道的数据库,报错”2003 can't connect to MySQL server on '' (10061 'unknown error')“ 一.开启 ...

  8. Flynn初步:基于Docker的PaaS台

    Flynn它是一个开源PaaS台,无论要部署的应用程序,你可以建立自己的主动性Docker容器集群的实现,能特性与组件设计大量參考了传统的PaaS平台Heroku.本文旨在从使用动机.基本对象.层次架 ...

  9. 基于 Docker 的微服务架构实践

    本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...

随机推荐

  1. 【VBA】获取文件夹下所有文本文件

    源码: 1 Sub 获取文件夹下所有文本文件() 2 Dim strPath As String 3 strPath = "G:\A\" 4 Dim MyFile As Strin ...

  2. 02:HTML

    HTML介绍 Web服务本质 import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen(5 ...

  3. docker安装nextcloud私人网盘,开启https配置证书

    docker安装nextcloud私人网盘 之前一直用的百度网盘最近svip超级会员到期了,续费要¥199元,对于一个打工人的我来说有点儿贵.作为技术人的一员,我就来发挥发挥自己的长处,来搭建一个私人 ...

  4. 数据同步Datax与Datax_web的部署以及使用说明

    一.DataX3.0概述 DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.ODPS.HBase.FTP等各种异构数据源之间稳定高 ...

  5. Spring Boot Docker

    1.  IDEA中配置Docker Docker默认只接受本地客户端的请求,为了能够远程访问它,首先要开放Docker的监听端口,运行外部应用可以访问 修改 /lib/systemd/system/d ...

  6. 关于Excel中表格转Markdown格式的技巧

    背景介绍 Excel文件转Markdown格式的Table是经常会遇到的场景. Visual Studio Code插件 - Excel to Markdown table Excel to Mark ...

  7. 38、linux中软件的安装方法

    38.1.rpm安装: rpm -ivh 包名# i:安装的软件: v:显示正在安装的软件信息: h:显示安装软件的进度: rpm -ql 包名 #查看安装包里的文件: rpm -qa 包名#查询包是 ...

  8. Flex中利用事件机制进行主程序与子窗体间参数传递

    在开发具有子窗体,或者itemrenderer的应用时,常常涉及到子窗体向父窗体传递参数或者从itemrenderer内的控件向外部的主程序传递参数的需求.这些都可以通过事件机制这一统一方法加以解决. ...

  9. NoSql非关系型数据库之MongoDB应用(一):安装MongoDB服务

    业精于勤,荒于嬉:行成于思,毁于随. 一.MongoDB服务下载安装(windows环境安装) 1.进入官网:https://www.mongodb.com/,点击右上角的 Try Free  , 2 ...

  10. js 获取系统当前时间,判断时间大小

    1.获取系统当前时间 getNowTime(tempminit) { if (!tempminit) { tempminit = 0; } var date = new Date(); date.se ...