4 ms·
Separate services helps a lot with bigger teams. No matter how much you modularize code -- which will gradually fall apart anyway unless you have custom tooling
by mjr00 3y ago
Separate services helps a lot with bigger teams. No matter how much you modularize code -- which will gradually fall apart anyway unless you have custom tooling that enforces API boundaries programmatically -- you're still tying people to the same runtime environment, which means you're tying people to the same libraries and underlying framework/operating system. Which means major library upgrades become nonstarters (too much code to test/change), and runtime upgrades are rare and challenging (hello, enterprises still running Java 6/7).
There's a balance and the "every function should be a microservice" approach is kind of insane, but "just use a monolith for everything" falls apart pretty quickly at larger team sizes.
- anotherhue 3y agoYou're right, I didn't give any numbers. IMO for every dozen engineers you are allowed one monolith (but now you call it a service).
- marcosdumay 3y ago> but now you call it a service What is a problem in itself. On every sane place, most of the "services" aren't providing any on-demand service, instead they are just thematic monoliths doing all of a part of a task. I'm settling on the opinion that a service-based architecture is always wrong. But people keep calling the good architectures by that name.
- jameshart 3y agoWell, you’re almost at the moment of enlightenment. Yes, all the good architectures are service based. And all service based architectures are wrong. Because all architectures are wrong. In the sense that there’s always another way you could have architected it that would be better for where you think you want to go next, than the way it is architected. Learn to accept that an evolving software system is always going to have a suboptimal architecture.
- marcosdumay 3y agoHum... No. You are misinterpreting my words here. I'm saying that I now strongly suspect that biasing the way you divide your software on a direction that gives you services will always make your life worse (probably by a lot). There's no philosophical allegory about perfect things not existing. There are a few things that really want to be services. You'll settle those on services whatever way you decide to architecture your software. But those are very few, and any push into doing it for more than the absolute minimum is harmful.
- vilunov 3y agoI've seen microservices with inadequate boundaries, much like what you just described with monoliths. This was due to product evolution, or maybe initial requirements were not fully understood when the new architecture was implemented. Only in microservices fixing these boundaries is much more difficult than in a single codebase. > "just use a monolith for everything" falls apart pretty quickly at larger team sizes. Absolutely! Don't put everything in a single monolith, develop several mediumliths with lower requirements for coupling code together, but keeping it small enough so that upgrades are bearable.
- downWidOutaFite 3y agoI'm a fan of libraries, not modules, for hard API boundaries. A library, developed and compiled separately and published with versioning, gives you a lot of the clean separation of services without the networking and system overhead. Dependencies should always point from the app to the library as much as possible, so the library should bring it's own dependencies instead of trying to reuse the app's framework/libraries.
- mjr00 3y agoLibraries sort of help but not really. In the end, if the main app is on Python 3.10, all libraries it uses must be capable of running on Python 3.10. And if you want to upgrade the app to 3.11, first you have to upgrade all libraries to support 3.11 (in addition to 3.10, since you'll likely have to do it piecemeal and not a single big-bang). This is to say nothing of the classic dependency hell[0] where the main app depends on library X and Y, but library X depends on Z==1.0.0 and library Y depends on Z==2.0.0. At which point you have to do some hacky stuff like JAR shading (which has its own problems, see log4shell) or vendoring the dependency under a new namespace. For a lot of use cases, specifically at larger orgs and where highly optimized performance isn't a big priority, the networking and operational overhead is a small price to pay for decoupling. [0] https://en.wikipedia.org/wiki/Dependency_hell https://en.wikipedia.org/wiki/Dependency_hell
- downWidOutaFite 3y agoPython and any other popular language will try hard to stay backward compatible, so that shouldn't be a problem. I have encountered in the other direction where a library wants to use new language features but the app's runtime doesn't support it yet. That can be considered a downside.
- phyrex 3y agoI’ve tried this but did not find it worthwhile in practice. Either you end up running multiple versions of the same library, which sucks terribly unless your library doesn’t have side effects, or you end up doing a huge versioning dance at every change for no benefit
- phyrex 3y agoYou say that like it’s a fact but Facebook has a humongous monolith and it works fine with tens of thousands of engineers working on it at the same time