Integrating microservices is hard. Based on real-life projects, we will discuss how to overcome the challenges in complex communications, asynchronicity and distributed transactions.
15. 24
Use Saga Instead of 2-Phase-Commit!
Personal
Identification
Check In
Barcode
Generation
Check-In
Local
Transaction
Barcode
Local
Transaction
Verification
Local
Transaction
Transaction Manager
Distributed
Many organizations have principles or guidlines they adhere to for microservices.
While following these principles we want to build resiliant, well documented, understandable, and flexible systems. Sometimes we may need to break the rules but we should do this consiously. Camunda and BPMN is a powerful tool in your tool box and can help you to build these qualitites into your systems.
My name is Paul Lungu
I’m a consultant with Camunda NA
That’s my daily driver the ridge rider.
Many customer are doing microservices or distributed systems in some form.
Weather its’s calling a restful service leveraging request response
Or building an event driven systems
Camunda is helping solve problems and challenges
There are things we cannot control.
What is resilience; Dealing with the things we cannot control.
The network is a dark and stormy place
We have many challenges to overcome
Our goal; Build Resilient Systems
Design for failure
Fail Fast
Keep failure local
Circuit Breaker Pattern -
Make sure failure doesn’t take down your system
What does this mean in more practical terms
Lets talk in a little detail about the challenges
Communication is complex.
In the rough seas it’s difficult to determine certain failure scenarios
Request doesn’t get there
Service Fails
Response doesn’t get back to the client
Workflows can be very small when used for these challenges.
We can encapsulate the functionality of the checkin using Camunda and BPMN
We can think of the workflow engine living inside this microservice
Now we can do things like
Retry
Fallback when things to workout
And much more
As a user I would still get a bad experience here if we haven’t considered the behaviour from the user perspective. How would you solve this?
Now with the state and functionality contained within this service.
We can consciously make the decision.
Because BPMN is natural documentation that provides tranparancy and observability into what’s happening real-time and historically.
Another way we can be resilient
Don’t let failure take down the entire system
We want to avoid this bad user experience.
Guide the user or service or even better handle the failure ourselves and provide a good response later.
This goes with for another service that using our service.
Avoid telling our end user; you need to start all over.
We have preserved our system so you can do the process all over again. Why did we have to do that? Because we have no way to preserve the state of what you did before the failure.
Save the user some work, then send the boarding pass when it’s ready.
It would be much better to contain the error and the state within the checking service.
Whenever a service can resolve failures itself, it encapsulates important behavior.
Reducing overall complexity in the system.
Creating a better experience for the user or client using the service
We have another big challenge.
A powerful pattern that often accompanies async are timers.
In this example we send a message to the barcode generator we then wait for a message to come back.
Of course we can only wait so long before we need to take other actions.
We want to make sure we keep the failure local and contained.
We can accomplish both with BPMN.
It’s easy to handle time and set up communication that is asynchronous.
Now we have a stateful service that can handle failure in an asynchronous way.
In distributed systems you cannot count on ACID transactions.
Distributed Transactions don’t scale well in distributed systems
Difficult to manage failure with two phase commit
Don’t use two phase commit with XA transaction manager
But we still have the problem
Saga pattern - compensation in BPMN
Eventual Consistency
Google two phase commit images two get a feeling for complexity.
Gross simplification of two phase commit
Has problems like it’s hard to debug when things go wrong and they will go wrong.
The engine can stitch together all the these activities and handle failures in the service.
It’s eventual consistency but that’s ok in this scenario.
Many other architecture options including
J2EE App Servers
Web-sphere
Web-logic
JBoss
Were going to focus on the microservice related architectures
Spring Boot
Wildfly Swarm
Each service is living on it’s own. They are autonomous.
Depending on how we design the BPMN we can flip the architecture a bit on it’s head.
You can use External Tasks to take advantage.
Your system can be a Polyglot of programming language and technologies.
It’s very easy to configure an external task client.
But sometimes the easiest things are the hardest to truly understand conceptually
In contrast to calling Java code, where the process engine synchronously invokes Java logic, it is possible to implement a Service Task outside of the process engine’s boundaries in the form of an external task.
In the push scenario we are calling code from our service task.
In the pull scenario we are waiting for our code to call us. This decouples our code from the workflow.