某跨国零售集团因ERP、CRM、仓储系统等孤立运行,导致订单处理流程涉及12个系统,人工操作占比达60%,错误率高达8%。通过Java实现的 服务编排与流程管理平台,可将跨系统协作效率提升40%,错误率降至1%,并支持动态流程调整。
本文基于 Spring Cloud + Flowable + RabbitMQ,从零构建支持 跨系统协调、动态流程编排、实时监控 的EAI系统,并提供深度代码实现。
客户端 → API网关 → 服务编排层 → 流程引擎 → 后端服务集群 → 数据总线
模块 | 功能 | 技术实现 |
---|---|---|
服务注册中心 | 微服务发现与健康检查 | Eureka + Spring Cloud Netflix |
流程编排引擎 | 定义、执行、监控业务流程 | Flowable BPMN 2.0 + 自定义活动 |
数据总线 | 跨系统数据同步与消息路由 | RabbitMQ + Spring AMQP |
监控与审计 | 流程执行追踪、性能指标、操作日志 | Prometheus + ELK日志栈 + 自定义Hook |
// Eureka服务器配置(application.yml)
server:
port: 8761
eureka:
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://localhost:8761/eureka/
// Eureka客户端配置(服务启动类)
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
@Configuration
public class RibbonConfig {
@Bean
public IRule loadBalancingRule() {
return new ZoneAvoidanceRule(); // 基于区域的权重轮询
}
}
<process id="orderProcess" name="订单处理流程">
<startEvent id="start" />
<sequenceFlow sourceRef="start" targetRef="createOrder" />
<serviceTask id="createOrder" name="创建订单"
flowable:class="com.eai.order.CreateOrderActivity" />
<sequenceFlow sourceRef="createOrder" targetRef="checkInventory" />
<serviceTask id="checkInventory" name="库存检查"
flowable:class="com.eai.inventory.InventoryCheckActivity" />
<exclusiveGateway id="inventoryCheckGateway" />
<sequenceFlow sourceRef="checkInventory" targetRef="inventoryCheckGateway" />
<sequenceFlow sourceRef="inventoryCheckGateway" targetRef="processPayment" >
<conditionExpression xsi:type="tFormalExpression">${inventoryAvailable}conditionExpression>
sequenceFlow>
<sequenceFlow sourceRef="inventoryCheckGateway" targetRef="rejectOrder" >
<conditionExpression xsi:type="tFormalExpression">${!inventoryAvailable}conditionExpression>
sequenceFlow>
...(后续支付、发货等节点)
process>
// 库存检查服务活动
@Component
public class InventoryCheckActivity implements JavaDelegate {
@Autowired
private InventoryService inventoryService;
@Override
public void execute(DelegateExecution execution) {
String productId = (String) execution.getVariable("productId");
boolean available = inventoryService.checkStock(productId);
execution.setVariable("inventoryAvailable", available);
}
}
// 流程启动服务
@Service
public class ProcessService {
@Autowired
private RuntimeService runtimeService;
public void startOrderProcess(OrderRequest order) {
Map<String, Object> variables = new HashMap<>();
variables.put("orderId", order.getId());
variables.put("productId", order.getProductId());
runtimeService.startProcessInstanceByKey("orderProcess", variables);
}
// 流程实例监控
public List<ProcessInstance> getActiveInstances() {
return runtimeService.createProcessInstanceQuery()
.processDefinitionKey("orderProcess")
.active()
.list();
}
}
// 订单状态变更消息发布
@Service
public class OrderProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendOrderStatusUpdate(String exchange, String routingKey, OrderStatusUpdateMessage message) {
rabbitTemplate.convertAndSend(exchange, routingKey, message);
}
}
// 消息实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderStatusUpdateMessage {
private String orderId;
private String status;
private LocalDateTime updateTime;
}
// 库存服务消费订单状态变更
@Service
public class InventoryConsumer {
@RabbitListener(queues = "order-status-queue")
@Transactional
public void handleOrderStatusChange(OrderStatusUpdateMessage message) {
if ("PAID".equals(message.getStatus())) {
inventoryService.allocateStock(message.getOrderId());
} else if ("CANCELLED".equals(message.getStatus())) {
inventoryService.rollbackStock(message.getOrderId());
}
}
}
// 服务调用熔断配置
@HystrixCommand(fallbackMethod = "fallbackInventoryCheck",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
})
public boolean checkInventoryWithCircuitBreaker(String productId) {
return inventoryService.checkStock(productId);
}
// 熔断降级方法
private boolean fallbackInventoryCheck(String productId) {
// 降级逻辑:返回默认值或缓存数据
return false;
}
# application.yml熔断配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
shareSecurityContext: true
// 流程事件监听器
@Component
public class ProcessAuditListener implements ExecutionListener {
@Autowired
private AuditService auditService;
@Override
public void notify(Delegate通知书 execution) {
AuditLog log = AuditLog.builder()
.processInstanceId(execution.getProcessInstanceId())
.activityId(execution.getCurrentActivityId())
.timestamp(new Date())
.build();
auditService.save(log);
}
}
// 自定义指标注册
@Component
public class ProcessMetrics {
private final Counter processInstanceCounter =
Counter.build()
.name("process_instance_total")
.help("Total number of process instances")
.labelNames("process_key", "status")
.register();
public void incrementProcessInstance(String processKey, String status) {
processInstanceCounter.labels(processKey, status).inc();
}
}
// 动态加载BPMN文件并部署
@Service
public class DynamicProcessDeployer {
@Autowired
private RepositoryService repositoryService;
public void deployProcess(String bpmnContent) {
Deployment deployment = repositoryService.createDeployment()
.addString("dynamicProcess.bpmn", bpmnContent)
.deploy();
System.out.println("Process deployed with ID: " + deployment.getId());
}
}
// 流程版本管理
@Service
public class ProcessVersionManager {
@Autowired
private RepositoryService repositoryService;
public void rollbackToVersion(String processKey, int version) {
List<ProcessDefinition> definitions = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(processKey)
.orderByProcessDefinitionVersion().desc()
.list();
if (!definitions.isEmpty()) {
ProcessDefinition target = definitions.get(version);
repositoryService.suspendProcessDefinitionById(target.getId(), true, "Manual rollback");
}
}
}
// BPMN并行网关示例
<parallelGateway id="parallelGateway" />
<sequenceFlow sourceRef="checkInventory" targetRef="parallelGateway" />
<sequenceFlow sourceRef="parallelGateway" targetRef="processPayment" />
<sequenceFlow sourceRef="parallelGateway" targetRef="prepareShipping" />
// 定义人工任务
@ActivityBehaviorDelegateClass(ManualApprovalActivityBehavior.class)
public class ManualApprovalActivity extends ActivityImpl {
// 自定义行为类实现
}
// 人工任务行为类
public class ManualApprovalActivityBehavior extends AbstractBpmnActivityBehavior {
@Override
public void execute(DelegateExecution execution) throws Exception {
TaskService taskService = execution.getEngineServices().getTaskService();
Task task = taskService.newTask();
task.setName("订单审批");
task.setAssignee("[email protected]");
taskService.saveTask(task);
execution.setVariable("taskId", task.getId());
leaveVN(execution);
}
}
// 使用JPA事务管理流程变量
@Service
@Transactional
public class OrderService {
public void completeOrderProcess(String processInstanceId) {
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
Order order = orderRepository.findById((String) processInstance.getVariable("orderId"))
.orElseThrow(() -> new RuntimeException("Order not found"));
order.setStatus("COMPLETED");
orderRepository.save(order);
runtimeService.signalEventReceived("orderCompleted", processInstanceId);
}
}
// 调用物流API完成发货
@Service
public class ShippingService {
@Autowired
private RestTemplate restTemplate;
public void shipOrder(String orderId) {
String url = "https://api.shipping.com/v1/shipments";
ShippingRequest request = new ShippingRequest(orderId);
ResponseEntity<ShippingResponse> response = restTemplate.postForEntity(url, request, ShippingResponse.class);
if (response.getStatusCode() == HttpStatus.CREATED) {
// 更新订单状态
}
}
}
# RabbitMQ集群配置示例
spring:
rabbitmq:
addresses: rabbit1:5672,rabbit2:5672,rabbit3:5672
publisher-confirms: true
publisher-returns: true
// 流程引擎配置(application.yml)
spring:
jpa:
hibernate:
ddl-auto: update
datasource:
url: jdbc:mysql://db-cluster/orderdb?autoReconnect=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
flowable:
database-schema-update: true
通过以上代码实现,我们构建了企业级EAI系统的完整解决方案:
最佳实践建议: