1

I'm developing a micro (or macro) service architecture. Due to small team size, instead of breaking down to complete small microservices, some services are slightly larger but still well bounded from a domain design perspective. We are now busy implementing a service that is responsible for user analytics and being able to create lists of user segments based on these analytics. These segments can then trigger actions in the application such as unlocking content in the CMS microservice, etc.

My pain here is that this user segment service is now in a situation that it has to be "aware" of many other services to perform these actions which feels like an anti-pattern and leans towards a distributed monolith design. Biggest loss on this approach is now other servicses are tightly coupled to this service and cant be updated without testing / updating this user list service itself first.

I can implement and do use asynchronous communication using protobufs as the message type (not GRPC as lambda doesn't support this). I get that this is better than syncrhonous communications because of possible time out issues, etc. but is that really all I can do to reduce coupling? Or am I missing some critical service design thinking.

HELP!

Daniel Blignaut
  • 121
  • 1
  • 4

1 Answers1

0

My pain here is that this user segment service is now in a situation that it has to be "aware" of many other services to perform these actions which feels like an anti-pattern and leans towards a distributed monolith design.

This is something which everyone faces when designing their system around micro-services architecture. Keep in mind there is no 100% separation of the services(except in some really rate cases like a data collector service or similar but even then it is somehow aware of the service which is feeding it with events). They have to communicate and be aware of each other in some way but the key is how much and how? The solution to this is mix of communication approaches(see this Answer) based on your business operations. What I mean by this that sometimes calling a micro-services is better then publishing an event to a queue. This really depends on your business operation.

Biggest loss on this approach is now other servicses are tightly coupled to this service and cant be updated without testing / updating this user list service itself first.

  • Tightly coupled. If by this you mean that an business-operation which is stopped if an action is not performed/executed in another services then this should be avoided in most cases. I said in most cases as sometimes this is not possible(for example if you have an Identity/Authentication micro-services or some other service like some cloud service which provides some essential functionality to you, you have to be dependent on that ;) ). How this can be avoided? For example make the operation finish without the result of the dependent micro-service and later update your Aggregate(Eventual Consistency). Consider using a Saga for this case. If this is not possible consider to merge those 2 micro-services to 1 or live with the fact that you have 2 micro-services highly coupled(at least for this one business operation). Other option is to duplicate data from micro-service-A in micro-service-B so that micro-service-B does not need to call micro-service-A every time it needs some data. Again this is not the solution for all scenarios. Check this answer for more information.
  • Testing. For testing purposes you should mock all cross micro-service calls and not block your Unit/Integration test by other services. This is a common approach in micro-services systems. This way your tests will not depend on other micro-service.

I can implement and do use asynchronous communication using protobufs as the message type (not GRPC as lambda doesn't support this). I get that this is better than syncrhonous communications because of possible time out issues, etc. but is that really all I can do to reduce coupling?

Yes you are right this will not solve your problem as your operation will still be blocked, but having asynchronous communication option through a queue will help you for other scenarios.

xargs
  • 2,741
  • 2
  • 21
  • 33