Live data from Hacker News

In Defence of Monoliths

techblog.bozho.net

31–40 of 76 posts

Re: In Defence of Monoliths

#31
post #17
post #7

Earlier quoted context omitted.

> The higher coupling in most monoliths also restricts a teams ability to try new things and take risks. I think it's you who's missing the point. That right there is why. Turning your monolith into a micro-service architecture should add up to basically: - Wrap your internal modules in your favourite form of RPC - Replace the modules with stubs that call the RPC If you need more work than that, the problem with your…

Don't forget that an RPC call can take longer to complete than a function call. Loose coupling doesn't imply that your program expects operations to routinely take 1ms to return results.

Or sometimes 10s, or never, or partial results, or dropped connections, or...

The network is not reliable.

Re: In Defence of Monoliths

#32
Yeah, my general rule is that unless your production environment is already so complex that you have multiple people who do strictly DevOps work, you should probably stick to a monolith. It's a lot easier to transfer state between multiple deployments of the same monolith than it is to go full microservices.

Microservices are a gigantic pain in the ass. They increase operational complexity significantly, and they will require you to make a lot of investments in building/buying/implementing infrastructure around things like logging, monitoring and config management. Your number of possible variables in QA explodes exponentially, and suddenly you have to worry about things like API versioning.

If all of this sounds easier than dealing with the tech / organizational debt in your monolith, then microservices may be right for you. Otherwise, save yourself the trouble and focus on scaling your business instead of your technology platform.

Re: In Defence of Monoliths

#33

Being a new "convert" to microservices, and coming from a classic OOA/D/P background, I read these critiques with great interest. I keep waiting for one that shows me what I'm missing. What I'm finding, however, is that many of these authors have such a broad understanding of microservices are that they miss any benefit. Then, of course, they complain about there not being any benefit, natch. I suspect -- and what I…

don't you think 150LOC is a bit extreme on the low side? I don't see how this is possible unless you compose services out of other services... and in that case it's probably a nightmare to debug anything. Can you elaborate a bit on types of things that this worked great for you?

I can't walk through a solution to a complex domain inside of a HN comment, but I can provide an overview of the theory.

Take a large monolithic app or framework. What I've found is that if a problem is properly coded, while you may have tens or hundreds of thousands of LOC, the actual code doing the work is quite small, on the order of hundreds or thousands of LOC. The rest of it is all "wiring".

Moving to pure FP means that a lot of the code structure of OOP disappears and you're left with just the critical pieces. This consists of composed functions performing translations on immutable chunks of data. Your functions become microservices and the composition of functions, scheduling, and moving around of data become Net/Dev Ops.

There are many ways to fall off the path here. You start using mutable data, you start associating services with business domains, you start coupling microservices together more tightly than necessary -- there's a ton of ways you can accidentally screw up, and then you're probably better off with a monolithic app.

Microservices should be like ls, cat, or chmod -- small pieces of composable functions that run directly in the O/S. They don't blow up the system when they fail, they do one thing and only one thing, they're configurable using command-line switches, they're transport-independent, and so on.

Re: In Defence of Monoliths

#34

Earlier quoted context omitted.

> Ensuring that a change in one micro service doesn't break things in another can be daunting. That is what I was referring to when I mentioned nebulous APIs. In a properly-designed system, each component (be it a module of a monolithic system or service in a microservice system) should be a black box with known APIs and no side effects. Part of defining the API is defining the acceptable values that can come across…

The more your system is broken down into smaller components the more you have to break an API to make a change. Unless all change consists of nothing but bug fixes and performance enhancements, changes to the API is as common as anything else. If your need is respond quickly to changing requirements this setup falls flat.

Yes, if services are too small than it will be hell. A lot of microservice proponents talk about how services should align to a "bounded context", essentially a domain of the business. That makes it more likely that (1) there are well defined interfaces between business domains and (2) changes will be grouped into a single service as opposed to requiring changes throughout the codebase.

Also, if it's being done right, you rarely "break" an API in a single blow. You add new functionality, possibly via a new API. You give your consumers ample time to migrate. Only then do you remove the old API. One of my old teams had a hard requirement that all APIs had to be backwards compatible for 2 versions, which was essentially a year. We got very good at adding functionality without any impact on consumers that had not upgraded yet.

Re: In Defence of Monoliths

#35
post #28
post #12

There's a dangerous, contagious illness that developers of every generation get that causes them to worry about architecture and getting "street cred" even more than they worry about solving business problems. I've fallen victim to this myself, because street cred is important to me. But it's a trap. An important meta-idea that encapsulates all of this is remember to solve your business problems as your first priorit…

I agree with you, but the opposite of this is also horrible. I'm working for a company where they only focused on business needs, and the result is horrible. Terrible, unwieldy codebases, full of bugs, have no security at all. It's hard to develop features, it suffers from feature creep, have absolutely no test coverage at all. It's important to find balance.

You're totally right: balance is the key. At least where you work there's a deployed product in production, though it is difficult and unwieldy. When you go the architecture astronaught direction, it's very easy to never make it into production at all!

Re: In Defence of Monoliths

#36
I'm not advocating for microservices, but I think the blog post fails to understand the difference between patching a single microservice and deploying a single microservice without needing to restart your entire environment stack, and patching a single module in a monolith which requires you to restart the entire monolith... Maybe that's not an actual issue but the author seems to disregard the fact that restarting a single microservice is explicitly different than restarting the entire monolith for the very reason that time may become an actual factor.

Re: In Defence of Monoliths

#37
post #26

Earlier quoted context omitted.

Nobody said anything about 1 VM per microservice. You're using the term "service" in a way I did not intend (and which is a carryover from other kinds of services) This is illustrative of the point I was making. One of the big benefits of microservices is the total decoupling of the code from the underlying hardware. Things are glued together by Ops, not by code. So you might have all the microservices in one VM -- o…

I don't understand properly the term micro service if services aren't separated in a "network" way.

You have an entire A-Class network(127.0.0.0) within a single VM. That makes ~2^24 possible adresses and 2^16 ports. Isn't that enough of a network?

Re: In Defence of Monoliths

#38
post #28
post #12

There's a dangerous, contagious illness that developers of every generation get that causes them to worry about architecture and getting "street cred" even more than they worry about solving business problems. I've fallen victim to this myself, because street cred is important to me. But it's a trap. An important meta-idea that encapsulates all of this is remember to solve your business problems as your first priorit…

I agree with you, but the opposite of this is also horrible. I'm working for a company where they only focused on business needs, and the result is horrible. Terrible, unwieldy codebases, full of bugs, have no security at all. It's hard to develop features, it suffers from feature creep, have absolutely no test coverage at all. It's important to find balance.

Sounds like they only focused on short-term business needs.

Maintainability and security are definitely business needs, but they're long-term instead of short-term, so it's easy for new companies to underinvest in them.

Re: In Defence of Monoliths

#39
post #36

I'm not advocating for microservices, but I think the blog post fails to understand the difference between patching a single microservice and deploying a single microservice without needing to restart your entire environment stack, and patching a single module in a monolith which requires you to restart the entire monolith... Maybe that's not an actual issue but the author seems to disregard the fact that restarting…

You know, nearly all software running out there does not need to be online 24x7. And for the tiny exception that needs, reducing restart time is just not the way to get that 99.9% uptime.

Re: In Defence of Monoliths

#40
post #36

I'm not advocating for microservices, but I think the blog post fails to understand the difference between patching a single microservice and deploying a single microservice without needing to restart your entire environment stack, and patching a single module in a monolith which requires you to restart the entire monolith... Maybe that's not an actual issue but the author seems to disregard the fact that restarting…

Not disagreeing with you, just adding some color.

We have a monolithic application (well, an application composed of many libraries that have a dependency tree, but live in the same process) that contains individually deployable services that talk to one another over RPC. So when you're patching part of the codebase, you can deploy a branch to the servers that are executing the code you've just changed, thus no need to restart the whole thing. But you still have the benefits of shared libraries, moving functionality between services, collapsing service calls that are no longer performant, adding new calls temporarily, etc.

In this model, you can introduce and remove service calls when it's useful, as opposed to as a result of how the code was put together. You will often do this for performance reasons, but just as often you'll do it for deployment flexibility. When you want to prototype something new, you can create a new service, branch the codebase, and have it talk to the rest of the infrastructure via service calls. When you're done you can keep it as a service, or, just as often, you can collapse the service back into other services so we don't have excessive RPC calls.

When would we consider moving to services backed by different codebases? If our company were to grow so large that highly disparate teams would want to manage their own dependency trees--that's around when it makes sense to me to go microservice. (I not sure I'd call it microservices then, more SOA).

Post reply on HN