Why Process Orchestration Is Critical for Scalable Backend Systems
The article explains how excessive if‑else logic in multi‑business middle‑platforms leads to maintenance nightmares and demonstrates, with concrete code and a real open‑source project, how a flow engine and plugin‑extension framework provide clean isolation, extensibility, and reliable execution of business processes.
Good programmers should stick to simple, fast solutions and avoid over‑design; the author initially dismissed workflow orchestration as unnecessary complexity.
Working in a middle‑platform team revealed that many business lines require slightly different logic, making pure code reuse impossible and forcing developers to litter the codebase with nested if statements.
if (biz == BizA || biz == BizB) {
// do something (common logic)
if (biz == BizA) {
// BizA‑specific handling
}
if (biz == BizB) {
// BizB‑specific handling
}
}When ten or more business variants are added, the number of branches explodes, developers cannot master all variations, and a single mistake can break unrelated services, leading to production incidents.
To solve the isolation and extensibility problems, the author proposes two techniques:
Use a flow engine to configure separate execution chains for each business.
Use a plugin‑extension engine so each business can implement its own divergent parts.
The open‑source MemberClub project (hosted on Gitee) applies both techniques. It provides a paid‑membership transaction solution and demonstrates how to build a middle‑platform system.
Configuring Flow Execution Chains
Different membership products require different purchase‑order flows. The class DemoMemberPurchaseExtension implements a purchase extension point and defines three chain configurations, as shown in the screenshot.
Defining Flow Nodes
Each node implements four methods: process, success, rollback, and callback.
Executing the Flow
At runtime a FlowChain.execute call supplies a context object and triggers the chain.
The engine links nodes like a Chain‑of‑Responsibility pattern. It iterates over each node, invoking process. If a process throws an exception, the engine runs rollback on the already‑executed nodes in reverse order. If all process calls succeed, it then calls success on each node in reverse order, followed by callback on every node.
Flow Engine Execution Principle
The core of FlowChain.execute is shown below.
public <T> void execute(FlowChain<T> chain, T context) {
Exception exception = null;
int index = -1;
for (FlowNode<T> node : chain.getNodes()) {
try {
node.process(context);
index++;
} catch (Exception e) {
if (e instanceof SkipException) {
CommonLog.warn("Current flow:{} sent Skip request, stop further execution", node.getClass().getSimpleName());
break;
}
exception = e;
break;
}
}
if (exception != null) {
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try {
node.rollback(context, exception);
} catch (Exception e) {
CommonLog.error("Rollback exception ignored, name:{}", node.getClass().getSimpleName(), e);
}
}
} else {
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try {
node.success(context);
} catch (Exception e) {
CommonLog.error("Success exception ignored, name:{}", node.getClass().getSimpleName(), e);
}
}
}
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try {
node.callback(context, exception);
} catch (Exception e) {
CommonLog.error("Callback exception ignored, name:{}", node.getClass().getSimpleName(), e);
}
}
if (exception != null) {
throw exception;
}
}The full source files are available in the MemberClub repository:
https://gitee.com/-/ide/project/juejinwuyang/memberclub/edit/master/-/memberclub.common/src/main/java/com/memberclub/common/flow/FlowChainService.java
MemberClub also integrates many useful frameworks and components, making it a valuable learning resource for SpringBoot‑based middle‑platform systems:
Mybatis‑plus
Sharding‑sphere (multi‑datasource sharding)
Redis / Redisson
Apollo
Spring Cloud (Feign / Eureka)
RabbitMQ
H2 in‑memory DB
Swagger
Lombok + MapStruct
Beyond these, the project showcases the implementation principles of several core components:
Flow engine
Extension‑point engine
Distributed retry component
General logging component
Product inventory management
Distributed lock component
Redis Lua scripting
Spring context utilities
All code is open‑source on Gitee and GitHub:
https://gitee.com/juejinwuyang/memberclub
https://github.com/juejin-wuyang/memberclub
Java Web Project
Focused on Java backend technologies, trending internet tech, and the latest industry developments. The platform serves over 200,000 Java developers, inviting you to learn and exchange ideas together. Check the menu for Java learning resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
