Live data from Hacker News

Microservices should form a polytree

bytesauna.com

91–100 of 121 posts

Re: Microservices should form a polytree

#91
post #88

I think what the article is doing wrong is treating all microservices the same. Microservices can be split into at least 3 different groups: - infrastructure (auth, messaging, storage etc.) - domain-specific business logic (user, orders) - orchestration (when a scenario requires coordination between different domains) If we split it like this, it's evident that: - orchestration microservices should only call business…

Yeah, as a rule of thumb, this is a considerably better abstraction. Unfortunately it's hard to keep a strong separation between orchestration and business logic in practice, and harder still to ensure the separation stays there over time.

Re: Microservices should form a polytree

#92
post #33

This is a fair enough point, but you should also try to keep that tree as small as possible. You should have a damn good reason to make a new service, or break an existing one in two. People treat the edges on the graph like they're free. Like managing all those external interfaces between services is trivial. It absolutely is not. Each one of those connections represents a contract between services that has be maint…

A contract that needs to be maintained at some level of quality even when you're deploying or overloaded.

Load shedding is a pretty advanced topic and it's the one I can think of off the top of my head when considering how Chesterton's Fence can sneak into these designs and paint you into a corner that some people in the argument know is coming and the rest don't believe will ever arrive.

But it's not alone in that regard. The biggest one for me is we discover how we want to write the system as we are writing it. And now we discover we have 45 independent services that are doing it the old way and we have to fix every single one of them to get what we want.

Re: Microservices should form a polytree

#93
At first this sounds cool but I feel like it falls apart with a basic example.

Let's say you're running a simple e-commerce site. You have some microservices, like, a payments microservice, a push notifications microservice, and a logging microservice.

So what are the dependencies. You might want to send a push notification to a seller when they get a new payment, or if there's a dispute or something. You might want to log that too. And you might want to log whenever any chargeback occurs.

Okay, but now it is no longer a "polytree". You have a "triangle" of dependencies. Payment -> Push, Push -> Logs, Payment -> Logs.

These all just seem really basic, natural examples though. I don't even like microservices, but they make sense when you're essentially just wrapping an external API like push notifications or payments, or a single-purpose datastore like you often have for logging. Is it really a problem if a whole bunch of things depend on your logging microservice? That seems fine to me.

Re: Microservices should form a polytree

#94
post #93

At first this sounds cool but I feel like it falls apart with a basic example. Let's say you're running a simple e-commerce site. You have some microservices, like, a payments microservice, a push notifications microservice, and a logging microservice. So what are the dependencies. You might want to send a push notification to a seller when they get a new payment, or if there's a dispute or something. You might want…

I don’t understand why you would have a logging microservice vs just having a library that provides logging that is used wherever you need logging.

Re: Microservices should form a polytree

#95
post #93

At first this sounds cool but I feel like it falls apart with a basic example. Let's say you're running a simple e-commerce site. You have some microservices, like, a payments microservice, a push notifications microservice, and a logging microservice. So what are the dependencies. You might want to send a push notification to a seller when they get a new payment, or if there's a dispute or something. You might want…

I don’t understand why you would have a logging microservice vs just having a library that provides logging that is used wherever you need logging.

Only good reason would be for bulk log searching, but a lot of cloud providers will already capture and aggregate and let you query logs, or there are good third party services that do this.

Pretty handy to search a debug_request_id or something and be able to see every log across all services related to a request.

Re: Microservices should form a polytree

#96

This seems cool if all you need is: call service -> Get response from service -> do something with response. How do you structure this for long running tasks when you need to alert multiple services upon their completion? Like what does your polytree look like if you add a messaging pub/sub type system into it. Does that just obliterate all semblance of the graph now that any service can subscribe to events? I am not…

> Like what does your polytree look like if you add a messaging pub/sub type system into it.

A message bus is often considered a clean way to deal with a cycle, and would exist outside the tree. I hear your point about the graph disappearing entirely if you use a message bus for everything, but this would probably either be for an exceptionally rare problem-space, or because of accidental complexity.

Message busses (implemented correctly) work because:

* If the recipient of the message is down the message will still get delivered when it comes back up. If we use REST calls for completion callbacks then the sender might have to do retries and whatnot over protracted periods.

* We can deal with poison messages. If a message is causing a crash or generally exceptional behavior (because of unintentional incompatible changes), we can mark it as poisoned and have a human look at it - instead of the whole system grinding to a halt as one service keeps trashing another.

REST/RPC should be for something that can provide an answer very quickly, or for starting work that will be signaled as complete in another way. Using a message bus for RPC is just as much of a smell as using RPC for eventing.

And, as always, it depends. The line may be somewhere completely different for you. But, and I have seen this multiple times, a directed cycle in a distributed system's architecture turns it into a distributed monolith: eventually you will reach a situation where everything needs to deploy at the same time. Many, many, engineers can talk about their lessons in this - and you are, as always, free to ignore people talking about the consequences of their mistakes.

Re: Microservices should form a polytree

#97
post #93

At first this sounds cool but I feel like it falls apart with a basic example. Let's say you're running a simple e-commerce site. You have some microservices, like, a payments microservice, a push notifications microservice, and a logging microservice. So what are the dependencies. You might want to send a push notification to a seller when they get a new payment, or if there's a dispute or something. You might want…

Is your example really a "triangle" though? If you have a broker/queue, and your services just push messages into the ether, there's no actual dependency going on between these services.

Nothing should really depend on your logging service. They should push messages onto a bus and forget about them... ie. aren't even aware of the logging service's existence.

Re: Microservices should form a polytree

#98
post #14

I might have a different take. I think microservices should each be independent such that it really doesn't matter how they end up being connected. Think more actors/processes in a distributed actor/csp concurrent setup. Their interface should therefore be hardened and not break constantly, and they shouldn't each need deep knowledge of the intricate details of each other. Also for many system designs, you would expl…

> I might have a different take. I think microservices should each be independent such that it really doesn't matter how they end up being connected.

The connections you allow or disallow are basically the main interesting thing about microservices. Arbitrarily connected services become mudpits, in my experience.

> Think more actors/processes in a distributed actor/csp concurrent setup.

A lot of actor systems are explicitly designed as trees, especially with regard to lifecycle management and who can call who. E.g. A1 is not considered started until its children A2 and A3 (which are independent of each other and have no knowledge of each other) are also started.

> Also for many system designs, you would explicitly want a different topology, so you really shouldn't restrict yourself mentally with this advice.

Sometimes restrictions like these are useful, as they lead to shared common understanding.

I'd bet an architecture that designed with a restricted topology like this has a better chance of composing with newly introduced functionality over time than an architecture that allows any service to call any other[1]. Especially so if this tree-shaped architecture has some notion of "interface" services that hide all of the subservices in that branch of the tree, only exposing the public interface through one service. Reusing my previous example, this would mean that some hypothetical B branch of the tree has no knowledge of A2 and A3, and would have to access their functionality through A1.

This allows you to swap out A2 and A3, or add A4 and A5, or A2-2, or whatever, and callers won't have to know or care as long as A1's interface is stable. These tree-shaped topologies can be very useful.

1 - https://www.youtube.com/watch?v=GqmsQeSzMdw

Re: Microservices should form a polytree

#99
post #31

Avoiding cyclic dependencies is good, sure. And they do name specific problems that can happen in counterexample #1. However, the reasoning as to why it can't be a general DAG and has to be restricted to a polytree is really tenuous. They basically just say counterexample #2 has the same issues with no real explanation. I don't think it does, it seems fine to me.

An AuthN/Z system would probably end looking like counterexample #2, which immediately raised a red flag for me about the article.

There’s a million reasonable situations where this pattern could arise because of you want to encapsulate a domain behind a micro service.

Take the simplest case of a CRM system a service provides search/segmentation and CRUD on top of customer lists. I can think of a million ways other services could use that data.

Re: Microservices should form a polytree

#100
post #31

Avoiding cyclic dependencies is good, sure. And they do name specific problems that can happen in counterexample #1. However, the reasoning as to why it can't be a general DAG and has to be restricted to a polytree is really tenuous. They basically just say counterexample #2 has the same issues with no real explanation. I don't think it does, it seems fine to me.

An AuthN/Z system would probably end looking like counterexample #2, which immediately raised a red flag for me about the article.

There's no particular reason an Auth system must be designed like counterexample #2. There's many ways to design that system and avoid cycles. You can leverage caching of role information - propagated via messages/bus, JWT's with roles baked-in and IDP's you trust, etc. Hitting an Auth service for every request is chaotic and likely a source of issue.
Post reply on HN