在前四篇文章中,我们从基础概念、流程设计、API 实战到 Spring Boot 集成,逐步构建了 Flowable 的知识体系。但企业级应用中,流程引擎很少孤立存在 —— 它需要与 CRM、ERP、支付系统等外部系统交互,还需应对异步回调场景。本文将聚焦外部系统如何调用流程引擎,以及如何集成 Redis Stream 作为回调队列,实现跨系统流程的高效协同。
一、外部系统调用 Flowable 的三种方式
外部系统与 Flowable 的交互通常围绕流程实例的创建、任务处理、状态查询三个核心场景,常见实现方式有以下三种:
1.1 直接调用 API(同步集成)
适合与 Java 系统的紧密集成,通过引入 Flowable 客户端依赖直接调用 API:
// 外部系统(如CRM)中的流程调用代码
@Service
public class CrmProcessService {
@Autowired
private RestTemplate restTemplate;
// 调用Flowable创建客户审批流程
public String createCustomerApprovalProcess(CustomerDTO customer) {
// 构建请求参数
Map<String, Object> params = new HashMap<>();
params.put("customerId", customer.getId());
params.put("name", customer.getName());
params.put("level", customer.getLevel());
params.put("applyTime", new Date());
// 调用Flowable的REST API
ResponseEntity<String> response = restTemplate.postForEntity(
"http://flowable-server:8080/flowable-rest/service/runtime/process-instances",
buildProcessRequest("customerApprovalProcess", params),
String.class
);
// 解析响应获取流程实例ID
JsonNode result = new ObjectMapper().readTree(response.getBody());
return result.get("id").asText();
}
// 构建流程请求对象
private ProcessInstanceRequest buildProcessRequest(String processKey, Map<String, Object> variables) {
ProcessInstanceRequest request = new ProcessInstanceRequest();
request.setProcessDefinitionKey(processKey);
request.setVariables(variables);
return request;
}
// 查询流程状态
public String getProcessStatus(String processInstanceId) {
ResponseEntity<String> response = restTemplate.getForEntity(
"http://flowable-server:8080/flowable-rest/service/runtime/process-instances/" + processInstanceId,
String.class
);
JsonNode result = new ObjectMapper().readTree(response.getBody());
return result.get("ended").asBoolean() ? "已完成" : "运行中";
}
}
适用场景:同架构下的系统(如 Java 微服务)、需要同步获取结果的场景
优势:实时性高、集成简单
注意事项:需处理 API 调用超时(建议设置restTemplate超时参数)、权限控制(可通过 OAuth2 令牌认证)
1.2 基于消息队列的异步集成
适合跨语言、跨架构系统,通过消息队列解耦调用方与 Flowable:
// 外部系统(如Python电商平台)发送流程启动消息到RabbitMQ
@Service
public class OrderProcessPublisher {
@Autowired
private RabbitTemplate rabbitTemplate;
public void startOrderProcess(OrderDTO order) {
// 构建消息体
ProcessMessage message = new ProcessMessage();
message.setType("START_PROCESS");
message.setProcessKey("orderDeliveryProcess");
message.setBusinessKey(order.getId());
Map<String, Object> variables = new HashMap<>();
variables.put("orderId", order.getId());
variables.put("amount", order.getAmount());
variables.put("items", order.getItems());
message.setVariables(variables);
// 发送到指定队列
rabbitTemplate.convertAndSend(
"flowable.process.requests", // 队列名称
message.getProcessKey(), // 路由键
message
);
}
}
// Flowable端的消息消费者
@Component
public class ProcessMessageConsumer {
@Autowired
private RuntimeService runtimeService;
@RabbitListener(queues = "flowable.process.requests")
public void handleProcessMessage(ProcessMessage message) {
if ("START_PROCESS".equals(message.getType())) {
// 启动流程实例
runtimeService.startProcessInstanceByKey(
message.getProcessKey(),
message.getBusinessKey(),
message.getVariables()
);
} else if ("COMPLETE_TASK".equals(message.getType())) {
// 处理任务完成消息
taskService.complete(
message.getTaskId(),
message.getVariables()
);
}
}
}
适用场景:异构系统(如 Java 与 Python/Go)、非实时依赖的流程
优势:解耦系统、提高容错性、削峰填谷
注意事项:需保证消息可靠性(持久化、确认机制)、处理重复消息(通过businessKey幂等控制)
1.3 基于 WebHook 的事件回调
通过配置 WebHook,让 Flowable 在流程状态变更时主动通知外部系统:
// 外部系统提供的回调接口(接收Flowable


7257

被折叠的 条评论
为什么被折叠?



