Tag: event driven architecture

Service vs Components vs Microservices – part 6

Part 1 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 2 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 3 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 4 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 5 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them

Text updated 27th of June 2021

As I explained in Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 5, to me a service is a logical boundary that is the technical responsible for a given business capability.
This means that the service owns all data, logic and UI for this capability everywhere it is used.

What does it mean that a service is a logical boundary?

As explained in Philippe Kruchten’s 4+1 view of software architecture, we should not automatically force the logical view to be the same as the physical implementation or for that matter the deployment view.
This often means that a service isn’t a single implementation or deployment artifact.

You’ve probably read that a microservice should follow the Single Responsibility Principle (SRP) – it should do one thing and do it well.
If we align microservices with business capabilities, such as Sales, Shipping, Marketing, Billing, Policy Management,
then the microservices would most like be fairly big, which goes against many of the qualities we like about microservices, such as:

  • Small (easy to comprehend)
  • Replaceable (discard the old and write a new in 2 weeks)
  • Upgradable (upgrade just the parts you want without interrupting other parts)
  • Fast startup/shutdown
  • Individually deployable

A large service is still individually deployable, but from a scaling point it’s typically all or nothing: either you scale the entire deployable unit or you don’t.

What if it is only certain use-cases that needed scaling? This is often harder with too big a deployable unit (what some people refer to a monolith) due to individual components inside the unit being too tightly coupled, like a tangled ball of yarn.

Continue reading “Service vs Components vs Microservices – part 6”

Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 5

Part 1 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 2 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 3 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 4 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 6 – Service vs Components vs Microservices

Text updated the 27th of June 2021

First of all, sorry to those who’ve been waiting for part 5. My schedule has been too busy to find focused time to write part 5 before now 😳 .

In part 4 we looked at building our services around functional areas or business capabilities/bounded-contexts.

We discussed that the business data and logic pertaining to a business capability must be encapsulated inside a service to ensure single source of truth for the data.

This also means that other services aren’t allowed to own the same data that another service owns because we want to avoid multi master services.

Since we want our service to be autonomous, i.e. the service should able to make a decision without having to communicate synchronously with other services, we also looked how to avoid 2 way communication (RPC, REST, GraphQL or Request/Response) between services.

The options we looked at were Composite UI’s and Data duplication over Events.

We also briefly discussed a 3rd option that involved a different view on services, where they’re not autonomous and services instead expose intentional interfaces and coordinate updates/reads between several System of Records (SoR) that them selves are autonomous. I believe that organizations with many large legacy systems (and most likely multi master Systems of Records) should look into the possibilities of the 3rd option, as I believe it may create less friction than trying to develop new autonomous services that are well aligned with business capabilities.

In part 5 I will continue discussing SOA and Microservices in the light of autonomous services.

Business Capabilities and Services

In part 4 I suggested building our services around functional areas or business capabilities/bounded-contexts.
I would like to tighten up that statement and rephrase to:

We should align our services with business capabilities.

Continue reading “Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 5”

Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 4

Part 1 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 2 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 3 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 5 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 6 – Service vs Components vs Microservices

Text update the 27th of June 2021

In part 3 we saw, that in order to ensure a higher degree of autonomy for our services, we need to avoid (synchronous) 2 way communication (RPC/REST/etc.) between services and instead use 1 way communication.

A higher level of autonomy goes hand in hand with a lower degree of coupling. The less coupling we have, the less we need to bother with contract and data versioning.
We also increase our services stability – failure in other services doesn’t directly affect our services ability to respond to stimuli.

But how can we get any work done, if we only use 1 way communication? How can we get any data back from other services this way?
Short answer is you can’t, but with well defined Service Boundaries you (in most cases) shouldn’t need to call other services directly from your service to get data back.

Service boundaries

What is a service boundary?
It’s basically a word that’s used to define the business data and functionality that a Service is responsible for. In Microservices: synchronous communication, data ownership and coupling we covered Service principles such as Boundaries and Autonomy in detail.
Boundaries determine what’s inside and outside of a Service. In part 2 we used the aggregate pattern to analyse which data belonged inside the Legal Entity service.
In the case of the Legal Entity service we realised that the association between Legal Entity and Addresses belonged together because LegalEntity and its associated Addresses were created, changed and deleted together. By replacing two services with one we gained full autonomy for the Legal Entity service whereby we could avoid the need for orchestration and handling all the error scenarios that can result of orchestrating data-changing calls between services (LegalEntity service and Address service).

In the case of the Legal Entity the issue of coupling was easily solved, but what happens when you have a more complex set of data and relationships between these data?
We could just pile all of that data into a single service and thereby avoid the problem of having data changes across process boundaries (i.e. between different services that are hosted in other OS processes or on different physical servers). The issue with this approach is that this quickly brings us into monolith territory. There’s nothing wrong with monoliths per se. Monoliths can be build using many the same design principles described here, e.g. as modules/components, that are bundled together and deployed as a single unit – where as microservices often are deployed individually (that’s at least one of the major qualities that people talk about in relation to microservices).
Continue reading “Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 4”

Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 2

Danish version: http://qed.dk/jeppe-cramon/2014/03/13/micro-services-det-er-ikke-kun-stoerrelsen-der-er-vigtigt-det-er-ogsaa-hvordan-du-bruger-dem-del-2/

Part 1 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 3 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 4 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 5 – Microservices: It’s not (only) the size that matters, it’s (also) how you use them
Part 6 – Service vs Components vs Microservices

Text updated the 23rd of June 2021

In Micro services: It’s not (only) the size that matters, it’s (also) how you use them – part 1, we discussed how the number of lines of code is a very poor measure for whether a service has the correct size and it’s totally useless for determining whether a service has the right responsibilities.

We also discussed how using 2 way (synchronous) communication between our services results in tight coupling and other annoyances, amongst other things communication related coupling, because data and logic often aren’t in the same service.

2 way (synchronous) communication between services also causes:

  • Higher latency due to network communication
  • Contractual-, data– and functional coupling
  • Layered coupling, because persistence logic often isn’t in the same service that owns the business logic
  • Temporal coupling, which means that our service can not operate if it is unable to communicate with the services it depends on
  • Lower services autonomy and less reliability, because our service depends on other services to perform its job
  • All of this also introduces the need for complex compensation logic due to the lack of reliable messaging and coordinating transactions.

imageReusable service, 2 way (synchronous) communication and coupling

Worst case, If we combine (synchronous) 2 way communication with nano- / micro-services, modelled according to e.g. the rule 1 class = 1 service, we have basically returned to the 1990s where Corba and J2EE/EJB’s and distributed objects ruled.

Unfortunately, it seems that new generations of developers, who did not experience distributed objects and therefore haven’t yet realized how bad an idea it was to overuse this, is bound to repeat history.
This time we have just switched technologies like RMI or IIOP out with HTTP+JSON instead.

Jay Kreps summed up the common Micro Service approach, using two way communication, very aptly:

image

Jay Kreps – Microservice == distributed objects for hipsters (what could possibly go wrong?)

Continue reading “Microservices: It’s not (only) the size that matters, it’s (also) how you use them – part 2”