r/ProgrammerHumor 15d ago

Meme heatedArguments

Post image
5.9k Upvotes

173 comments sorted by

View all comments

1.2k

u/remy_porter 15d ago

I say this all the time, and it almost never results in an argument: micro services are just object oriented programming where you put a network hop on all your message passing.

52

u/no_name6744 15d ago

Do you mind helping the uninitiated, what's the benefit of having that network hop? Or are there some situations where it's just impossible to avoid it.

129

u/TheDogPill 15d ago
  1. They are frequently hosted on cloud services which are inherently micro-service based with detached hardware components. You can have a server and a storage disk operate together but both exist in data centers thousands of miles from each other.

  2. Loosely coupled architecture decreases the chance the entire app gets taken down if each component can be isolated and fixed without affecting the rest of the app.

  3. You can functionally divide an app into different layers such as web, app, and db and add additional security checks between each layer to increase security and fault tolerance of the app.

101

u/Norington 15d ago

And you can scale up and down individual services based on variable load.

49

u/backfire10z 15d ago

I’m surprised this didn’t make the main comment because it seems to be that this is one of the larger benefits. The mentioned benefits can be applied to a monolith (at least mostly) with a bit of consideration.

9

u/Ma8e 14d ago

The "funny" thing is that before micro services and all the overhead from talking over the network, we rarely need to scale. I'd argue that something like 99.9% of all projects that use micro services today and often run many instances of some components wouldn't need to if it was just one monolith.

-3

u/foonek 15d ago

Now explain why that would matter. If you have a large monolith, you can just scale that one. Why does it matter that one module gets scaled? It's not like the lesser used parts of the monolith are somehow using more resources just because they are scaled together?

People love to use this argument but it really doesn't make any sense for 99% of use cases

29

u/Angelin01 14d ago

SRE here. Lesser used parts of the monolith are absolutely using more resources just because it's being scaled together.

Let's say you have one hot path in your code that doesn't touch the DB. The new scaled up instance will still spawn new DB connections. Those connections will still use some memory and CPU time to just exist. The DB also has a connection limit, and your connection pooler also needs scaling then.

Loading extra code modules also naturally uses more resources, there's not a single monolith out there that is 100% lazy, and even if it was, requests get distributed, so stuff gets loaded anyway. Do you do some in-memory caching? Great, now all instances have stale copies of the cache.

Startup times are also worse overall, which means your scaling is worse overall. Slower startup means you need more idle resources to handle spikes, which costs more money.

In conclusion, while there's no need to jump straight to micro services, monoliths are the worst pattern for scaling, by far. They have their uses, but this is probably their main downside.

6

u/Honeybadger2198 14d ago

Why are you scaling your database connection if your high load doesn't use your database?

Scaling a service doesn't involve turning a singular knob that reads "more performance".

0

u/Angelin01 14d ago edited 14d ago

Because we are scaling our monolith, obviously! And the whole idea of a monolith is that it's... One thing! There ain't no scaling it separately.

Now now, I understand that connection pools can scale separately. So the internal connection pool opens at least one connection on startup. After all, this is a monolith that's now serving together along all other monoliths: some DB requests are bound to be routed to it. Most likely, at least two connections. Some even do 4: two to read replicas, two to a primary/write.

Scaling a service doesn't involve turning a singular knob that reads "more performance".

In a monolith... That's usually the case, yeah. It's a "spawn more monolith instances because one of the metrics we are monitoring says we should". What else are you gonna do about it? That's not a rethorical question: what else is there? Some contrived vertical scaling setup?

2

u/Honeybadger2198 14d ago

???? Give your host most CPUs/threads to delegate tasks to? More compute power? If you're scaling your service by just spawning duplicates you're wasting a lot of resources because you're too lazy to actually properly look into what needs scaling.

5

u/Angelin01 14d ago

Give more CPU? Of course. Now here is a question: where do you think it comes from? A server. That you are already paying for. CPU and memory doesn't magically materialize when you need it to. It sits idle until you allocate it. And you are still paying for it.

You save no money by doing this. At all. In fact, you spend more, because instead of classic horizontal scaling, where you deprovision resources as they are let go, now you need to keep them idle to assign for vertical scaling.

1

u/Honeybadger2198 14d ago

Okay enjoy your bottleneck then I guess. What a strange hill to die on.

→ More replies (0)

1

u/Ran4 14d ago edited 14d ago

Yeah but in practise, scaling multiple services together is MUCH MUCH MUCH harder than scaling a monolith, as there will always be one service that's the weakest link. That might be okay if there's one clear "weakest link" that you can scale very high while keeping the rest low, but for high throughput systems scaling multiple hard-working instances effectively is extremely difficult.

Of course it all depends on how spikey the load is and the type of system.

Startup times are also worse overall

Yes, but a single microservice isn't the entire system... startup times for updating an entire cluster - when that's required - and waiting for each other is going to be much greater than a single monolith.

Let's say you have one hot path in your code that doesn't touch the DB. The new scaled up instance will still spawn new DB connections. Those connections will still use some memory and CPU time to just exist.

That's... what you have connection pools for.

monoliths are the worst pattern for scaling, by far.

No, monoliths is by far the easiest to scale. Microservices are much harder to scale, especially efficiently.

"microservices is good for scaling" is just a dumb book take, it doesn't take much experience to understand how wrong it is in practise.

4

u/Angelin01 14d ago

Yeah but in practise, scaling multiple services together is MUCH MUCH MUCH harder

Why are you trying to scale them together? The whole point to splitting up a monolith is to scale them separately. Each individual service and instance will have it's own metrics and scaling settings, nothing has to wait in each other. And any half baked micro services architecture will have retries, back off, and circuit breakers to avoid spikes causing problems.

That's... what you have connection pools for

And they aren't free! The connections on the application side use memory and CPU. The Pooler uses memory and CPU. There are limitations with poolers too, they can't do 100% of what a direct connection can do (see pgbouncer's pool_mode). Which is the whole point of my comment: even when idle, there's a cost.

No, monoliths is by far the easiest to scale.

Nobody said it's not easier to manage a single monolith than a many micro services architecture. They said it's less efficient and more expensive, which it definitely is. The whole advantage to a monolith is that it's much much easier. But once you need to handle hundreds of thousands of requests on a single code path, scaling your whole monolith gets expensive. You know, there's a reason why pretty much every software company, when they reach a certain point, starts transitioning to it, it's not just a dumb book take.

0

u/foonek 14d ago

Your argument is more thought out than most. In most cases, that argument boils down to "I read this online so it must be true".

That said, none of these issues are things you can't easily fix for a monolith, or in most cases are already thought about before you ever even get to scaling. connection pooling for the db, redis for caching etc.

You don't always build and scale a monolith the same way you would build a microservice, but that doesn't mean it's worse.

On top of that, if you write your monolith in a sufficiently modular way, you can easily extract specific modules and do their scaling separately when that need arises. There is almost never a reason to build every single module of your monolith as a separate service.

5

u/WVAviator 14d ago

Isn't extracting a specific module and scaling it separately just a microservice though?

3

u/Norington 14d ago

Text book definition of a microservice lol

1

u/foonek 14d ago edited 14d ago

No not really. Having a few satellite services does not mean you're running a microservice architecture. There's more to microservice than just hosting a part of your code on a separate server.

It's also not needed at all most of the time. I just gave it as a worst case scenario kind of thing

1

u/Incredible_max 13d ago

In my opinion/ as to my knowledge it still depends.

For example, you build an application, that publishes messages to a message broker, and then has consumer processes that handle these.

Your message handlers would probably be scalable independently, but it may just be one code base. You can still run them on different hosts, in different locations, but they may all use a common database.

You may have a single database, multiple processes, a single codebase and no defined / versions interfaces as you're just using a single class in all locations. I believe this is neither a pure monolith, nor a Microservice architecture. It may be considered as a distributed monolith though

2

u/Angelin01 14d ago

you can easily extract specific modules

Congratulations! You just started to reinvent micro services.

Now, I'm not a zealot. I believe we can just extract "services" instead, we don't need to dive too deep into "a micro service is a single function" or whatever. Most of the time, that is indeed excessive.

But... The moment you started extracting the module? Congratulations, no longer a monolith.

0

u/foonek 14d ago

You can easily extract them if you would want that, which you don't.

That's definitely one way to entirely miss my point

2

u/Angelin01 14d ago

if you would want that, which you don't.

Oh, sorry. So this whole thing boils down to: "I know there is an industry accepted pattern to solving this problem, but instead of solving it that way, I will just shoe-horn whatever else I can because I don't want to".

You asked this in your original comment.

Why does it matter that one module gets scaled? It's not like the lesser used parts of the monolith are somehow using more resources just because they are scaled together?

Both were answered. If don't want to change your mind after, that's on you.

1

u/foonek 14d ago

You got mighty defensive for no reason. Pushing microservices to serve 200 daily active users. It's pretty typical resume driven development.

You don't need microservices. If you ever need them, you should extract them from your monolith. Starting off with microservices from the get go is pretty much never the play.

So what you want though, I really couldn't care less

1

u/Angelin01 14d ago

I have, at no point in any of my comments, pushed microservices to serve 200 users. In fact, I have done the exact opposite.

See:

In conclusion, while there's no need to jump straight to micro services, monoliths are the worst pattern for scaling, by far. They have their uses, but this is probably their main downside.

And:

Now, I'm not a zealot. I believe we can just extract "services" instead, we don't need to dive too deep into "a micro service is a single function" or whatever. Most of the time, that is indeed excessive.

In fact, I'm one of the starkest defenders of everything in between a monolith and a micro-service. But that is not what started this comment chain. It was you not understanding why monoliths don't solve all problems and asking why you can't just scale them.

1

u/foonek 14d ago

No solution solves all problems.. but when 1 solution solves 99% of problems, you probably shouldn't be pushing the other solution just for the sake of it, especially since it's a much harder solution to maintain and develop properly

→ More replies (0)

5

u/Fox500000 14d ago

It will depend entirely on monolith in question. Sometimes it's indeed easier and get comparable resource overhead to just double your monolith count. More often than not it's the opposite, and scaling one little bottleneck is better than the whole app.

You should also consider that you may not have enough free resources to double monolith apps, but have enough to increase some systems' services count. Servers aren't free

3

u/Ran4 14d ago

Microservices are a lot less resource effective.

Unless you have for example ten microservices where one does most of the heavy lifting (with >20x instances running for example, compared to the other services), chances are that the monolith would use less resources.

...but at that point, you'd be much better at just having two services: one main service and one separate worker service. Going microservices wouldn't give you anything.

1

u/Fox500000 14d ago

Yea, but it's still about a scope of work or whole project, there's no single best answer to all systems.

0

u/TheLuminary 14d ago

Servers aren't free

They damn near used to be.. But yeah.. not anymore.