Live data from Hacker News

Don't start with microservices – monoliths are your friend

arnoldgalovics.com

241–250 of 468 posts

Re: Don't start with microservices – monoliths are your friend

#242
post #229

Earlier quoted context omitted.

Because there is no newly invented architecture called "modular monolith" - monolith was always supposed to be MODULAR from the start. Micro services were not an answer to monolith being bad. Something somewhere went really wrong with people's understanding and there is bunch of totally wrong ideas. That is also maybe because a lot of people did not knew they were supposed to make modules in their code and loads of m…

> monolith was always supposed to be MODULAR from the start Well, that certainly is sensible, but I wasn't aware that someone had to invent the monolith and define how far it should go. Alas, my impression is that the term "monolith" doesn't really refer to a pattern or format someone is deliberately aiming for in most cases, but instead refers to one big execution of a lot of code that is doing far more than it shou…

No one had to invent the monolith or define how far it should go; it was the default.

Microservices came about because companies kept falling into the same trap - that because the code base was shared, and because organizational pressures mean features > tech debt, always, there was always pressure to write spaghetti code rather than to refactor and properly encapsulate. That doesn't mean it couldn't be done, it just meant it was always a matter of time before the business needs meant spaghetti.

Microservices, on the other hand, promises enforced separation, which sounds like a good idea once you've been bitten by the pressures of the former. You -can't- fall into spaghetti. What it fails to account for, of course, is the increased operational overhead of deploying all those services and keeping them playing nicely with each other. That's not to say there aren't some actual benefits to them, too (language agnostic, faults can sometimes be isolated), but the purported benefits tend to be exaggerated, especially compared to "a monolith if we just had proper business controls to prevent engineers from feeling like they had to write kluges to deliver features in time".

Re: Don't start with microservices – monoliths are your friend

#243

Earlier quoted context omitted.

> no good reason How about deployment speed? If I’ve got a microservice collecting events off a queue and writing a csv out to S3 on a schedule, it’s really nice to be able to add a column and deploy in minutes without having to rebuild and deploy a giant monolith. It also allows for fine grained permissions: that service can only read from that specific queue and write to that specific bucket. People throw around “d…

Why not... > branch from whatever branch is in prod > implement change on that branch (in this case adding a column), test > deploy to prod I realize the build and deployment process may be more complex than that making it hard... but it doesn't have to be. I agree that a microservice OR even another system (a collection of services) is a good solution if you need to make quick iterative changes, and you can't do so…

That workflow is exactly what I do, but it's on a small codebase rather than on a big one.

The benefits of working on a small repo include:

* Faster compilation (only depend on exactly the libraries you need)

* Faster testing (only need to run the tests which are actually relevant)

* Easier to understand for new joiners because there's just less code to sift through

* Faster startup (this is probably java specific - the classloader is slooow)

* No (okay, fewer) rebase wars

* Easy to see what's currently being worked on because the Pull Requests tab isn't 200 long

* Very fast rollbacks without needing to recompile a git revert (just hotswap the container for that particular service). You can't do this in a monolith without risking rolling back someone else's important changes.

Re: Don't start with microservices – monoliths are your friend

#244
post #229

I wonder why no one ever talks about architectures in the middle between those two - modular monoliths. The point in time where you're splitting your codebase up in modules (or maybe are a proponent of hexagonal architecture and have designed it that way from the beginning), leading to being able to put functionality behind feature flags. That way, you can still run it either as a single instance monolith, or a set o…

Because there is no newly invented architecture called "modular monolith" - monolith was always supposed to be MODULAR from the start. Micro services were not an answer to monolith being bad. Something somewhere went really wrong with people's understanding and there is bunch of totally wrong ideas. That is also maybe because a lot of people did not knew they were supposed to make modules in their code and loads of m…

> Because there is no newly invented architecture called "modular monolith" - monolith was always supposed to be MODULAR from the start.

Isn't "non-modular monolith" just spaghetti code? The way I understand it, "modular monolith" is just "an executable using libraries". Or is it supposed to mean something different?

Re: Don't start with microservices – monoliths are your friend

#245
post #112
post #87

Earlier quoted context omitted.

Single writer multiple readers, ideally with permissions to enforce, is a useful hybrid. Enforce going through the front door if you want side-effects. Reporting and ad-hoc data enrichment can be painful to materialize otherwise. When you have multiple bits of code responsible for writing the same columns, maintaining global invariants becomes much harder. I can still see rationale for exceptions to the rule, e.g. st…

Caveat: I am really not qualified to discuss the nuances (because I have never used microservices so the little I know is based on reading a bit on those here and on other online forums). "Single writer multiple readers", yes, this is what I would probably use, but yet again, wasn't the "promise" of Microservices being able to work in total isolation? If I have one table (e.g. "Customer") which is written by one spec…

Microservices mean that different parts of your code are now communicating via (e.g.) HTTP instead of function calls.

It changes the situation regarding deployment, but it does not miraculously absolve you from changing code when data formats change. How could it?

Re: Don't start with microservices – monoliths are your friend

#246
The best start right now is to make two micro services:

All your services in one executable (one docker image)

Your UI (in another docker image)

From there you're free to separate things out more and more over time if you so choose. Having those two separate makes it so that you are required to at least have some kind of ingress controller that maps requests one way and UI assets another, so expanding should come easy at that point.

Re: Don't start with microservices – monoliths are your friend

#247
Actually monoliths maybe faster than microservices.

Consider monolith -> cpu l1 cache -> end user

Microservice -> account servive -> foo service -> l1 cache -> end user

Ie monolith goes directly to cou cache

Microservice goes to network calls which are mich slower than cpu cache.

Also with microservices you will need distributed application performance metric for call tracing. Distributed central logging. Container orchestration platform to run all the services.

Re: Don't start with microservices – monoliths are your friend

#248

I wonder why no one ever talks about architectures in the middle between those two - modular monoliths. The point in time where you're splitting your codebase up in modules (or maybe are a proponent of hexagonal architecture and have designed it that way from the beginning), leading to being able to put functionality behind feature flags. That way, you can still run it either as a single instance monolith, or a set o…

I agree with your position, I'm a big fan of the modular monolith approach. I took a look at your post. This is one thing that jumped out to me: > Because the people who design programming languages have decided that implementing logic to deal with distributed systems at the language construct level... isn't worth it I'm not sure if this is just a dead end or something really interesting. The only language I really k…

Recent languages do have syntax related to -concurrency- though.

Languages pre multi-core probably provided a VM/library, as you say, for threading, and then said "generally you should minimize threads/concurrency" (which for mainstream languages were the same thing).

Languages since then have embraced concurrency at the syntax level, even if not embracing threading. Node has event listeners and callbacks (and added async/await as a syntactical nicety), go has goroutines (with special syntax to indicate it), etc.

It's interesting that while languages have sought to find ways to better express concurrency since it became necessary to really use the chips found in the underlying hardware, they largely haven't sought to provide ways to better express distribution, leaving that largely to the user (and which has necessitated the creation of abstracted orchestration layers like K8s). Erlang's fairly unique in having distribution being something that can be treated transparently at the language level.

Mind you, that also has to do with its actor based concurrency mechanism; the reason sending a message to a remote process can be treated the same as sending a message to a local process is because the guarantees are the same (i.e., "you may or may not get a response back; if you expect one you should probably still have a timeout"). Other languages that started with stronger local guarantees can't add transparent remote calls, because those remote calls would have additional failure cases you'd need to account for (i.e., Java RMI is supposed to feel like calling a function, but it feels completely different than calling a local function. Golang channels are synchronous and blocking rather than asynchronous and non-blocking, etc. In each case you have a bunch of new failure conditions to think about and address; in Erlang you design with those in mind from the beginning)

Re: Don't start with microservices – monoliths are your friend

#249

Earlier quoted context omitted.

I've argued for a long time that microservices should grow out of a monolith like an amoeba. The monolith grows until there is a clear section that can be carved off. Often the first section is security/auth, but from there it's going to be application specific. A modulith could be just another step in the carve up process. But, there is no right answer here. Application domain, team size, team experience, etc... all…

In my experience with enterprise software one of the things that cause most trouble is premature modularization (sibling to the famous premature optimization). Just like I can't understand how people can come up with the right tests before the code in TDD, I can't understand how people can come up with the right microservices before they start developing the solution.

Perhaps a better way to think of "writing the tests first" in TDD approaches (or, more generally, test-first development, which is a term that has gone out of favor) is that you write test cases in that testing framework to express your intent and then from there can start to exercise them to ensure correctness. It's not a crime to change them later if you realize you have to tweak a return type. But writing them up front necessitates a greater depth of thinking than just jumping in to start hacking.

Not doing this runs the risk of testing what you did, not testing that it's right. You can get lucky, and do it right the first time. Or you can make a bunch of tests that test to make sure nothing changed, with no eye as to whether it's what anybody actually wanted in the first place.

Sitting down with somebody for whom TDD is natural is educational and makes it very hard to argue against it, particularly for library code.

Re: Don't start with microservices – monoliths are your friend

#250

Earlier quoted context omitted.

Thank you for sharing, and I agree with you- In my humble opinion microservices are "hot" because in theory you can scale a lot with them if you are able to do cloud provisioning. Microservices needs DevOps+Orchestration Service. A good example of microservices architecture is how K8s is designed: I think it is an overkill for most average needs, so think twice before entering in microservice trip tunnel.

Microservices solve pretty much one problem: you have a larger organization (> 10 devs, certainly > 100) and as a result the coordination overhead between those devs and their respective managers and stakeholders is significantly limiting overall forward progress. This will manifest in various concrete ways such as "microservices allow independent component release and deployment cycles" and "microservices allow fine…

This is a pretty critical point. The drum I tend to beat is that the positive read of microservices is that they make your code reflect your org chart.

(If they don't do this, and that usually resolves into developers each owning a bunch of microservices that are related concepts but distinct and are context-switching all the live-long day, you've created the reverse of a big ball of mud: you've created a tar pit. Companies used to brag to me when they had 250 microservices with 100 developers, and I don't think any of those companies are going concerns.)

Post reply on HN