Beauty of #microservices: part 6 managing state is a teamwork

1 Introduction

This blogpost is inspired by several blogposts about microservices and it is based on the blogpost [REF1] “Architecting #cloud-friendly application architecture #apparch (inspired by #microservices)” http://improving-bpm-systems.blogspot.ch/2015/04/architecting-cloud-friendly-application.html

See also the previous blogposts of “Beauty of #microservices” series.

2 Managing state is a teamwork

Obviously, a solution or an application implemented with microservices is a set or suite of stateful and stateless microservices. The chapter 7 of REF1 provides a classification of microservices. The stateful microservices are those which:
  1. manage some resources
  2. provide legacy functionality 
  3. assemble (implicitly and explicitly) other microservices
Each stateful microservice must be, ideally, idempotent to contribute to managing state.

Microservices, which manage some resources, may have a few impotency pitfalls to be avoided. For example, the read operation may be not idempotent if concurrent updates are possible. The update (or write) operation may be not idempotent if it can change some metadata, e.g. modification date. Also, idempotency may depend on a particular operation. The safest way is to create a small “shell” to guarantee the idempotency and a unique ID for each invocation.

Also, a small “shell” is only the option for microservices, which provide legacy functionality (they are considered as black boxes).

Microservices, which implicitly assemble other microservices, are a real pain because they have to be carefully reviewed about their idempotency. A possible approach for their idempotency is to re-execute again such a microservice. If all the microservices, which are invoked from it, are idempotent and don’t have any human involvement then such a re-execution will be idempotent as well.

Microservices, which explicitly assemble other microservices, may create some “check-points” (similar to mainframe batch systems) to start their re-execution from the last “passed” checkpoint. Of course, the data associated with checkpoints must be stored somewhere else as records. ( A similar approach can be found in http://www.theidentitycookbook.com/2016/06/blockchain-for-identity-access-request.html )

3 Error recovery (and distributed transactions)

As microservices form a distributed system, the error recovery is very difficult.

Explicit assembly of microservice, e.g. a business process in BPMN, can implement the error recovery in the following way.

Imagine a process fragment with three automated activities (A, B, and C) to be executed as a transaction. Each of those activities is an invocation of a microservice and the normal execution sequence is E2-A-B-C-E4.  Because any of those microservices may fail, this fragment contains the intermediate event E3 to intercept a failure and an activity for Error Recovery Procedure (ERP); the latter may be a human activity.

The first pass (with a failure of activity B ) has the following sequence:


The second pass (with a failure of activity C) has the following trace:

E2-A(already done)-B(done)-C(failed)-E3-ERP

The third pass (with no failures) has the following trace:

E2-A(already done)-B(already done)-C(done)-E4

Activity A was executed 3 times, but it did the real work only at the first time – two other times were ignored because it is idempotent.

An extension with a timeout can be found in http://improving-bpm-systems.blogspot.ch/2014/08/bpm-for-digital-age-shifting.html

This way can be used also for implementing distributed transactions (please, note, some compensation activities may be necessary).

A similar approach was described at http://www.grahamlea.com/2016/08/distributed-transactions-microservices-icebergs/

4 Conclusion

Microservice architecture requires common efforts from microservices to achieve
  • state management, 
  • error recovery and 
  • distributed transactions.

No comments: