微服务编排引擎 Netflix/Conductor 的精简/升级版实现 Brook

背景

这几年低代码的概念被说得很多,却不是什么新概念,这本身已经算是历史悠久了。从广义甚至可以说,平时我们做的代码设计:抽象、模块化、链条化、脚本化等,本身就是在"造"一个低代码引擎来降低/减少重复的工作量。

虽然网络上概念火热、讨论众多,但是作为一个后端开发者却没有什么好的选择------90%都是纯表单驱动的搭建工具。而我更想要一个原始的编排引擎,能构建出微服务编排、工作流等:

  • 模型驱动为主
  • 扩展简单方便
  • 可以调试定位
  • 只有点和线

实现

我调研了众多的引擎实现方案,发现比较契合的有 conductortemporal 。其中 conductor 是通过 DSL 进行流程编排,而 temporal 则通过写代码进行编排(可以更好地解决流程调试 DEBUG 的问题)。感兴趣的,可以点击链接进行更多地了解。

对于编排方式,秉承(中心化)用户不引入 SDK 、不写代码,可视化编排工具能更好集成的原则,现阶段我更倾向于选择 DSL。

但是在深度研究使用 conductor 后,我发现 conductor 的几个重要缺陷:

  • 不支持接口级流程编排(接口级编排恰恰是微服务编排的主要场景:多个接口按组合形成一个新的接口)。接口级是需要乃至毫秒级响应的接口。
  • 节点(Task)扩展很麻烦,主逻辑中存在大量具体节点相关的逻辑
  • 调度性能差

所以,结合多年的工作流和流程编排经验,我重新实现了 conductor,取名为 Brook。Brook 非常的轻量,不仅支持微服务,还支持应用内逻辑的编排执行(像责任链一样,还可以是动态的)。同时它不仅能中心化部署,还是嵌入到应用中运行。

Brook 仓库地址:github.com/mytang0/bro...

快速使用

为了最大限度地发挥 Brook 引擎的轻量级特性,其核心组件(仅依赖于一些必要的工具包)和使用 SPI(服务提供商接口)的中间件扩展之间进行了刻意的分离。因此,无论应用程序实现框架如何,都可以无缝依赖引擎JAR并初始化相关实例。

不使用 Springboot

xml 复制代码
<dependencies>
    <dependency>
        <groupId>xyz.mytang0.brook</groupId>
        <artifactId>>brook-engine</artifactId>
        <version>${brook.version}</version>
    </dependency>
</dependencies>

Springboot(推荐)

xml 复制代码
<dependencies>
    <dependency>
        <groupId>xyz.mytang0.brook</groupId>
        <artifactId>>brook-spring-boot-starter</artifactId>
        <version>${brook.version}</version>
    </dependency>
</dependencies>

样例(Demo)

运行

  • 克隆项目
bash 复制代码
git clone https://github.com/mytang0/brook.git
  • 导入 IDE
  • 运行Demo(brook-demo/brook-demo-spring)

DSL

只有一个 HTTP 节点的流程定义

bash 复制代码
{
  "name": "test-http",
  "description": "for showtime",
  "taskDefs": [
    {
      "type": "HTTP",
      "name": "test-http",
      "input": {
        "uri": "http://127.0.0.1:8080/flow/metadata",
        "method": "GET",
        "params": {
          "flowName": "${flow.input.flowName}"
        }
      }
    }
  ],
  "output": "${test-http.output}"
}

SPI

简单的编排节点扩展(Task 扩展)

typescript 复制代码
package xyz.mytang0.brook.demo.service;

import xyz.mytang0.brook.common.utils.JsonUtils;
import xyz.mytang0.brook.common.utils.TimeUtils;
import xyz.mytang0.brook.spring.boot.annotation.Taskable;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class DemoService {

    @Taskable(type = "test-void", description = "for testing")
    public void vd() {
    }

    @Taskable(type = "test-hello", description = "for testing")
    public String hello(String name) {
        return "Hello, " + name + " .";
    }

    @Taskable(type = "test-list", description = "for testing")
    public String list(List<Object> list) {
        return "list: " + JsonUtils.toJsonString(list);
    }

    @Taskable(type = "test-array", description = "for testing")
    public String array(Object[] array) {
        return "array: " + JsonUtils.toJsonString(array);
    }

    @Taskable(type = "test-map", description = "for testing")
    public String map(Map<String, Object> map) {
        return "map: " + JsonUtils.toJsonString(map);
    }


    @Taskable(type = "test-throw-iae", description = "for testing")
    public void throwIae() {
        throw new IllegalArgumentException();
    }

    @Taskable(type = "test-timeout", description = "for testing")
    public void timeout(Integer sleepSeconds) {
        if (sleepSeconds == null) {
            sleepSeconds = 5;
        }
        TimeUtils.sleep(sleepSeconds, TimeUnit.SECONDS);
    }
}
相关推荐
橘猫云计算机设计3 小时前
基于Springboot的自习室预约系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·毕业设计
秋书一叶4 小时前
SpringBoot项目打包为window安装包
java·spring boot·后端
pwzs4 小时前
Spring MVC 执行流程全解析:从请求到响应的七步走
java·后端·spring·spring mvc
小兵张健4 小时前
互联网必备职场知识(4)—— 共情沟通能力
后端·产品经理·运营
AskHarries5 小时前
使用 acme.sh 自动更新 SSL 证书的指南
后端
Chandler246 小时前
Go:反射
开发语言·后端·golang
pwzs6 小时前
深入浅出 MVCC:MySQL 并发背后的多版本世界
数据库·后端·mysql
盒子69106 小时前
go for 闭环问题【踩坑记录】
开发语言·后端·golang
刘大猫267 小时前
Arthas monitor(方法执行监控)
人工智能·后端·监控
追逐时光者7 小时前
MongoDB从入门到实战之MongoDB简介
后端·mongodb