Untangling Microservices, or Balancing Complexity in Distributed Systems

Untangling Microservices, or Balancing Complexity in Distributed Systems

The microservices honeymoon period is over. Uber is refactoring thousands of microservices into a more manageable solution [1]; Kelsey Hightower is predicting monoliths are the future [2]; and even Sam Newman is declaring that microservices should never be the default choice, but rather a last resort [3].

What’s going on here? Why have so many projects become unmaintainable, despite microservices’ promise of simplicity and flexibility? Or are monoliths better, after all?

In this post, I want to address these questions. You will learn about common design issues that turn microservices into distributed big balls of mud – and, of course, how you can avoid them.

[Read More]

Anti-Pattern: Optimistic Consistency

Ladies and Gentlemen, lo and behold a new consistency model - “Optimistic Consistency”. Implementation of this pattern is quite simple: commit as many transactions as you want, against as many storage mechanisms as you need. That’s all. Let’s see an example. Example Say as the result of some user’s operation the system has to: Modify data in MongoDB Publish some events to Kafka Update search model in Elasticsearch; and Execute an operation on some remote system You implement this logic by executing those operations one after another. [Read More]

Zen of Software Engineering

There is a pet peeve of mine, that I’m encountering way too often: the condition I call Silverbulletitis. This virus spreads among developers on many levels — juniors, seniors, and even architects. In this post I’d like talk about why this condition is dangerous, and how it can be treated. Symptoms All too often you can hear statements that some tool or technique is bad, but another one is the greatest thing since sliced bread. [Read More]

Tackling Complexity in CQRS

Tackling Complexity in CQRS

The CQRS pattern can do wonders: it can maximize scalability, performance, security, and even “beat” the CAP theorem. Nonetheless, CQRS has acquired a controversial name because of the complexity it introduces. For instance, in his article on CQRS, Martin Fowler argues that the pattern should be applied sparingly and even cautiously:

  • “… for most systems CQRS adds risky complexity”
  • “… you should be very cautious about using CQRS”
  • “So while CQRS is a pattern that’s good to have in the toolbox, beware that it is difficult to use well and you can easily chop off important bits if you mishandle it.”

From my point of view, the CQRS-induced complexity is largely accidental, and thus can be avoided. To illustrate my point, I want to discuss the goal of CQRS, and then analyze 3 common sources of accidental complexity in CQRS-based systems.

[Read More]

Finding Proper Scopes for Unit Tests

In my previous rant post on TDD I’ve argued that the majority of the problems many experience doing TDD are caused by testing in too narrow scopes - using classes as units of testability, instead of functional use cases. However, widening the scope of the test too much is just another extreme. So how one finds the sweet spot? In this post I’d like to share the heuristic that I use.

[Read More]

Tackling Complexity in the Heart of DDD

Tackling Complexity in the Heart of Domain-Driven Design

Let’s do a little experiment: try to explain the gist of Domain-Driven Design to someone who has no clue about it. This, especially doing it succinctly, is not easy. Heck, I struggle with it myself. Bounded contexts, entities, domain events, value objects, domains, aggregates, repositories… where do you even start?

To find the order in the apparent chaos, I want to analyze the DDD methodology from a rather unusual perspective — by applying Domain-Driven Design to Domain-Driven Design itself. After all, this methodology is intended to deal with complex domains, isn’t it?

[Read More]