标签:receive run only reserve business exactly sample discuss careful
转自:https://blog.bernd-ruecker.com/how-to-implement-long-running-flows-sagas-business-processes-or-similar-3c870a1b95a8
Long running flows can span from a few milliseconds up to several months or years (see What are long running processes? for details). Note that after some discussions I switched my wording from “long running processes” to “long running flows”.
When implementing these flows within your business application (or microservice architecture) you have to think about certain requirements, especially state handling and subsequent challenges like monitoring and versioning. Visualization of flows might come in handy. How can you tackle these requirements? I want to discuss the basic alternatives in this article:
The simplest option to get started is to add some state information to already existing entities. Think of a simple order application, then it might look like this:
class Order {
String id;
Customer customer;
List<OrderItem> items;
static enum GoodsDeliveryStatus {
NOTHING_DONE,
GOODS_RESERVED,
GOODS_PICKED
}
boolean paymentReceived = false;
GoodsDeliveryStatus deliveryStatus = GoodsDeliveryStatus.NOTHING_DONE;
boolean shipped = false;
//...
}
Advantages:
Disadvantages:
Once bitten, twice shy! Hence I am personally not a fan of this alternative, as I have seen it too often growing uncontrollably into a home-grown state machine (I have described this in the 7 sins of workflow).
However, if your requirements are simple enough, and you are sure it will stay like this for a while, you can go down this route. Just be honest with yourself — don’t do it just because you have a bad feeling about existing tools without concrete reasons. You may have based this on misconceptions which I plan to describe to you below. Sorry — once bitten…
A somehow similar concept is to store the state in entities but separated from your core domain entities. So you could have the following entity for the order:
class OrderSaga {
String orderId;
static enum GoodsDeliveryStatus {
NOTHING_DONE,
GOODS_RESERVED,
GOODS_PICKED
}
boolean paymentReceived = false;
GoodsDeliveryStatus deliveryStatus = GoodsDeliveryStatus.NOTHING_DONE;
boolean shipped = false;
}
This alternative has the advantage that the state is now clearly separated from your core domain entities, keeping the concepts pretty clear. And it does not introduce big downsides, all other forces are comparable to saving the state in the domain entities.
You can leverage existing state machines, often named workflow engine, process engine, orchestration engine or the like. Using for example the open source Camunda library you could express the flow like this:
private void createFlow() {
engine.getRepositoryService().createDeployment()
.addModelInstance(Bpmn.createExecutableProcess("order")
.startEvent()
.serviceTask().name("Retrieve payment").camundaClass(DoPaymentAdapter.class)
.serviceTask().name("Fetch goods").camundaClass(PickGoodsAdapter.class)
.serviceTask().name("Ship goods").camundaClass(ShipGoodsAdapter.class)
.endEvent().camundaExecutionListenerClass("end", OrderCompletedAdapter.class)
.done()
).deploy();
}
As you can see there are some classes containing logic attached. Afterwards this flow can be executed on the engine directly. The engine will take care of state handling and can even visualize the flow graphically, e.g. for later monitoring (as it also records a lot of audit data):
You could also use a graphical modeler to create the flow which is especially helpful if the flow gets more complex than our simple example. The good thing is: it is totally up to you to decide if you want to use code or graphics. Either way you can leverage visualization at least in operation.
The graphical flow looks like this, Camunda uses the ISO standard BPMN for modeling and visualization:
Advantages:
Disadvantages:
Rejecting state machines or appropriate engines is often done as a result of misconceptions — what a bummer! When selecting the right product and applying it properly later on, you can leverage the advantages without realizing the risks mentioned.
The state machine market is cluttered making the process of product selection challenging. Quick research reveals already 5 market categories:
To make the decision possible, you must first think about your use case. The order example in this post is best solved with a tool from the first category because you can easily leverage a lightweight engine but do complex flows with it. Additionally that provides you with a lot of additional features like visualization.
Sample code for the order process using Camunda is part of the flowing retail example.
I recently had an interesting discussion about using Routing Slips. I want to include it in this post as the pattern is relatively unknown but could also provide a solution.
Let’s assume our order process is handled by multiple microservices which communicate via messages or events. You can see this in action in the flowing retail example. Using a routing slip, the steps to process an order are:
Advantages:
Disadvantages:
So far, I have not found a very good reason to prefer the routing slip over the engine approach for the kind of flow shown in this example but I hope this post might trigger some discussions or comments.
There are different approaches to handle the state for long running flows. When researching on the web you get the impression that only state in entities is really known, especially if you face Microservices or Sagas (from the Domain Driven Design Community).
Personally, I think the state machine approach is most often better suited which is not that surprising: You have state, use a state machine. But in the past most existing tools were too complicated and scared developers away. That was the reason why we created the open source platform Camunda in the first place. And it has really changed in the recent years, there are now lightweight engines available which deserve a honest look at.
As for the question what approach to use: as always — it depends.
How to implement long running flows, sagas, business processes or similar
标签:receive run only reserve business exactly sample discuss careful
原文地址:https://www.cnblogs.com/rongfengliang/p/10351157.html