1. 引言

本教程将探讨如何使用Orkes Conductor和Spring构建事件驱动微服务。我们将利用Conductor通过HTTP接口和服务工作流来编排微服务。

2. 事件驱动微服务

微服务为创建可独立扩展和管理的模块化架构提供了绝佳方案。开发者通常将微服务设计为单一职责服务,专注于做好一件事。然而,应用流程通常需要协调多个微服务才能实现业务目标。

事件驱动架构通过事件系统稳健地促进微服务间通信,确保流程的可扩展性和持久性。因此,事件驱动微服务近年来广受欢迎,在实现异步流程时尤为实用。

2.1. 事件驱动系统的局限性

尽管在解耦服务交互方面表现出色,事件驱动系统仍面临几个挑战:

  • 难以可视化执行流程 – 所有微服务通信都通过事件总线进行,导致业务流程难以可视化和推理。这使得故障识别、调试和恢复更加困难。通常需要使用分布式追踪和集中式日志来解决这个问题。
  • 缺乏统一的应用状态管理 – 每个服务通常维护自己的本地数据库,作为该服务的记录系统。例如,信用卡服务可能包含信用卡支付列表及相关信息的数据库。但在跨多个服务调用时,应用的整体状态是分布式的,导致流程可视化、故障补偿处理以及特定时间点状态查询变得复杂。
  • 构建简单,扩展困难 – Spring等框架简化了可连接各种发布/订阅系统的事件驱动应用构建。但开发者往往需要投入大量时间解决系统运维、处理大规模工作负载扩展或构建复杂连接规则等挑战。

3. 使用Conductor的事件驱动架构

Netflix最初将Conductor构建为微服务编排平台。Netflix开发者设计并构建Conductor旨在创建事件驱动微服务并解决上述部分局限性。

作为编排器,Conductor允许我们通过代码或JSON定义服务执行流程,并支持使用任何语言SDK连接服务或编写服务工作流。Conductor作为完全开源的平台,采用Apache 2.0许可证运行。

Conductor的多语言特性允许我们使用任何语言编写服务工作流,甚至可以在单个应用流程中混用不同语言的服务和工作流。

Conductor使我们能够创建可复用的、遵循单一职责原则的事件驱动服务来响应事件。还可用于通过持久化队列连接通过HTTP暴露的服务。

4. 使用Conductor和Spring构建事件驱动微服务

现在,我们通过一个Spring Boot应用示例,展示如何利用Conductor编排微服务。

4.1. 设置Orkes Conductor

Orkes Conductor可通过多种方式配置:

  1. 使用Docker本地部署
  2. 使用免费的开发者沙箱环境Playground

遇到Conductor相关问题?可以加入Slack社区交流。

4.2. 方法1 – 使用Docker本地安装运行

首先确保设备已安装Docker。

然后使用以下Docker命令启动服务器(端口9090)和UI(端口1234):

docker run --init -p 9090:8080 -p 1234:5000 --mount source=redis,target=/redis \
--mount source=postgres,target=/pgdata orkesio/orkes-conductor-community-standalone:latest

创建一个简单的Spring Boot应用,实现两个功能:

  1. 使用Conductor创建微服务工作流
  2. 编排以下两个服务:

使用Conductor任务工作流创建简单服务工作流(无需暴露HTTP接口):

@WorkerTask(value = "fraud-check-required")
public FraudCheckResult isFraudCheckRequired(BigDecimal amount) {
    return fraudCheckService.checkForFraud(amount);
}

创建并行执行的工作流:

  1. 调用示例HTTP接口获取客户详情(https://orkes-api-tester.orkesconductor.com/api
  2. 运行我们刚实现的欺诈检查服务工作流

使用以下命令执行工作流,可通过*http://localhost:1234/workflowDef/microservice_orchestration*访问:

curl -X 'POST' 'http://localhost:9090/api/metadata/workflow' \
     -H 'accept: */*' \
     -H 'Content-Type: application/json' \
     -d '{
         "name": "microservice_orchestration",
         "description": "microservice_orchestration_example_workflow",
         "version": 1,
         "tasks": [
             {
                 "name": "fork_task",
                 "taskReferenceName": "fork_task_ref",
                 "inputParameters": {},
                 "type": "FORK_JOIN",
                 "forkTasks": [
                     [
                         {
                             "name": "fraud-check-required",
                             "taskReferenceName": "fraud-check-required_ref",
                             "inputParameters": {
                                 "amount": "${workflow.input.amount}"
                             },
                             "type": "SIMPLE"
                         }
                     ],
                     [
                         {
                             "name": "get_customer_details",
                             "taskReferenceName": "get_customer_details_ref",
                             "inputParameters": {
                                 "http_request": {
                                     "uri": "https://orkes-api-tester.orkesconductor.com/api",
                                     "method": "GET",
                                     "accept": "application/json",
                                     "contentType": "application/json"
                                 }
                             },
                             "type": "HTTP"
                         }
                     ]
                 ]
             },
             {
                 "name": "join_task",
                 "taskReferenceName": "join_task_ref",
                 "type": "JOIN",
                 "joinOn": [
                     "get_customer_details_ref",
                     "fraud-check-required_ref"
                 ]
             }
         ],
         "inputParameters": [
             "amount"
         ],
         "schemaVersion": 2,
         "restartable": true
     }'

通过HTTP POST请求运行新创建的工作流:

curl -X 'POST' \
'http://localhost:9090/api/workflow/microservice_orchestration' \
-H 'accept: text/plain' \
-H 'Content-Type: application/json' \
-d '{
    "amount": 1000.00
}'

在Orkes Conductor UI的"Executions"页面查看工作流执行ID验证执行结果。

现在深入探讨如何在应用中使用这种服务编排。我们将暴露一个执行该工作流的接口,创建使用事件驱动设计编排微服务的新API接口:

curl -X 'POST' \
'http://localhost:8081/checkForFraud' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
    "accountId": "string",
    "amount": 12
}'

4.3. 方法2 – 使用Orkes Playground

按以下步骤创建免费账户并使用Playground实时测试Conductor:

  1. 登录 https://play.orkes.io/
  2. 创建账户开始使用Orkes Conductor

在Playground中创建新工作流,或为方便测试直接使用以下工作流: 在Playground中查看工作流

建立Orkes Playground与工作流之间的连接需要创建应用:

  1. 在Orkes Playground导航到访问控制 > 应用
  2. 点击"创建应用"并提供应用名称
  3. 选择"应用角色"为"工作流"
  4. 点击"创建访问密钥"并保存密钥ID和密钥

授予工作流执行权限:

  1. 在"权限"部分点击"+添加权限"
  2. 在"工作流"选项卡选择"microservice_orchestration",在"任务"选项卡选择"fraud_check_required"
  3. 选择"EXECUTE"权限并添加

打开工作流,在application.properties文件中配置生成的密钥ID和密钥,将conductor.server.url替换为https://play.orkes.io/api

conductor.security.client.key-id=your_key_id
conductor.security.client.secret=your_key_secret
conductor.server.url=https://play.orkes.io/api

运行应用,工作流将轮询Conductor任务并在可用时获取任务。

使用Spring Boot应用中创建的http://localhost:8081/checkForFraud接口,它将使用play.orkes.io作为Conductor后端服务器运行工作流。

5. 结论

事件驱动微服务为构建可扩展、响应迅速的软件系统开辟了新可能。本文介绍了事件驱动微服务的基础知识,突出了其优势和挑战。

我们探讨了微服务如何凭借其模块化和单一职责特性,为构建复杂应用提供坚实基础。

本文源代码可在GitHub获取。


原始标题:Event-Driven Microservices With Orkes Conductor