对微服务实现工作流自动化的一些注意点

18-11-18 banq
         

您的公司可能希望采用微服务架构并应用工作流自动化。我在这篇博客文章中没有深入探讨一些注意点:

您会遇到以下问题:

  • 范围和边界(“您希望自动化什么工作流程以及如何将其映射到您的环境中的多个微服务或有界上下文”)。
  • 堆栈和工具(“我可以使用哪种工作流引擎?”)
  • 架构(“我是否将工作流引擎集中或分散?”)
  • 治理(“谁拥有工作流模型以及如何部署?”)
  • 操作(“我如何控制?”)

在这篇博文中,我给出了一些关于你必须做出的核心架构决策的指导。我将提供简化的答案,以帮助您开始并获得关于这个复杂主题的第一个方向。

由于所有理论都是灰色的,我想使用易于理解和遵循的具体业务示例来讨论某些方面。使用这个我按顺序检查以下几个方面:

  • 跟踪或管理  - 编排或编排?
  • 3通信备选方案:使用命令和事件的异步通信,RPC-ish点对点通信,使用工作流引擎的工作分配
  • 中央或分散的工作流引擎
  • 工作流模型的所有权

案例

我在本文中使用的示例是一个简单的订单履行应用程序,可作为在GitHub上使用源代码的流动零售示例应用程序。流动零售的一个很酷的事情是,它实现了不同的架构选择,并提供不同编程语言的样本。所有示例都使用工作流引擎,Camunda BPMZeebe

跟踪还是管理?orchestration choreography

是orchestration 还是choreography?后者通常被视为更好的选择(基于Martin Fowler的微服务文章)。这通常与事件驱动的体系结构相结合。

在这样一个精心设计的架构中,您会发出某些所谓的域事件,每个感兴趣的人都可以对这些事件采取行动。这是一个广播。这个想法是你可以简单地添加新的微服务来监听事件而不改变任何其他事情。这样的工作流程无处可见。

但随着一系列事件被发送而演变,危险在于你忽略了更大规模的流量,在我们的例子中是订单履行。

跟踪

一个简单的解决方法是至少跟踪事件流。根据具体的技术架构,您可能只需添加一个工作流引擎来读取所有事件,并检查它们是否可以与跟踪流相关联。

Flowing-retail显示了使用Kafka和Kafka-Connect的实现示例:

https://github.com/berndruecker/flowing-retail/tree/master/kafka/java/choreography-alternative/zeebe-track 和https://github.com/berndruecker/kafka-connect-zeebe.

管理journey 

这是非侵入性的,因为您不必更改架构中的任何内容。但它可以让您立即开始做事,通常,这会导致从简单跟踪流程到真正管理流程的过程。

orchestration 或choreography

良好的架构通常是orchestration 和choreography的混合体。公平地说,没有一些经验就很难平衡这两种力量。但我们看到很多证据表明这是正确的方法,所以绝对值得投入时间。(banq注:混合使用带来复杂性)

工作流引擎的作用 - 三种架构替代方案

如何使用工作流引擎建立架构以实现这种平衡?可以替代下面三种架构:

  • 通过命令和事件进行异步通信(通常使用消息或事件总线)
  • 请求/响应(通常是REST)的点对点通信
  • 按工作流引擎分配工作到微服务

通过总线ESB实现命令和事件进行异步通信

该架构依赖于用于异步通信的中央总线。不同的微服务连接到该总线。编排逻辑和相应的编排流程由微服务拥有。工作流程可以向总线发送新命令(“嘿付款,请为我取回一些钱”)或等待事件发生(“谁有兴趣,我查到了O42的付款”)。

  • 典型总线ESB工具:Kafka,RabbitMQ(AMQP),JMS。 
  • 工作流引擎的作用:超时处理,管理活动链/流,支持有状态的企业集成模式,聚合器或重定序器,一致性和补偿处理,又称Saga模式
  • 实现示例:https//github.com/berndruecker/flowing-retail/tree/master/kafka/java
  • 优点:微服务的时间解耦; 适用的事件驱动架构可以减少耦合; 许多失败场景(例如缺少的响应消息)对开发人员是透明的,因此他正确地考虑了这些情况。
  • 缺点:需要消息或事件总线作为中心组件,这不容易操作。大多数开发人员对异步通信并不熟悉。

通过请求/响应进行点对点通信

在这种架构中,您只需主动调用其他微服务,最常见的是以同步阻塞方式。最常见的方法是REST。通常从注册表中检索端点。工作流引擎可以协调REST调用,也可以帮助解决远程通信的挑战:

  • 典型工具:REST,SOAP,gRPC; 
  • 工作流引擎的作用:状态恢复模式(如状态重试),超时处理,管理活动链/流程,一致性和补偿处理 (banq注:这里SpringCloud提供的断路器回退等功能有作用)
  • 实现示例:https//github.com/berndruecker/flowing-retail/tree/master/rest
  • 优点:大多数开发人员易于设置和理解; 提供良好的工具。
  • 缺点:调用看起来像是本地的,因此开发人员经常忘记分布式系统的复杂性; 需要应用弹性模式(例如断路器,状态重试,......)。

根据工作流引擎分配工作驱动微服务

在这种架构中,工作流在微服务之间分配工作,这意味着它本身就成为某种总线。微服务可以订阅工作流的某些工作,并通过某种队列获取任务。 

  • 典型工具:外部任务(Camunda BPM)或Workers(Zeebe)。
  • 工作流引擎的作用:沟通渠道,超时处理,管理活动链/流程,一致性和补偿处理。
  • 实现示例:https//github.com/berndruecker/flowing-retail/tree/master/zeebe
  • 优点:易于设置; 良好的操作工具。
  • 缺点:工作流引擎成为架构的核心部分,需要适当地运行; 仅通过工作流程在微服务之间进行通信 - 或者需要建立第二种通信方式(例如REST或消息传递)。

结论

如果客户对Kafka或Messaging没有任何经验,那么很难在旅途中确定这一点。因此,他们可能更善于使用基于REST的架构,特别是如果他们深入了解Spring Boot和Spring Cloud,那么一些挑战就相对容易解决。

如果客户已经接受了域驱动设计(DDD)和事件,甚至利用了像Akka或Axon这样的框架,那么包含工作流引擎的事件驱动方法可能是最佳选择。

(banq注:基于EventSourcing的工作流引擎目前还没有,建议自己实现,参考:

从微服务到工作流:Jet订单系统演变过程分享,另外该文提到将工作流引擎纳入微服务内部,那么微服务就不是微服务了,而是单体服务了,因为其内部包含了一个复杂的流程。)