6 ms·
> And think of the sheer number of libraries - one for each language adopted - that need to be supported to provide common functionality that all services need,
by bob1029 3y ago
> And think of the sheer number of libraries - one for each language adopted - that need to be supported to provide common functionality that all services need, like logging.
This is the #1 reason we quit the microservices game. It is simply a complete waste of mental bandwidth to worry about with the kind of tooling we have in 2023 (pure cloud native / infiniscale FaaS), especially when you have a customer base (e.g. banks & financial instutitions) who will rake you over hot coals for every single 3rd party dependency you bring.
We currently operate with one monolithic .NET binary distribution which is around 250 megs (gzipped). Not even the slightest hint of cracks forming. So, if you are sitting there with a 10~100 meg SaaS distribution starting to get nervous about pedantic things like "my exe doesnt fit in L2 anymore", then rest assured - Your monolithic software journey hasn't even begun yet.
God forbid you find yourself with a need to rewrite one of these shitpiles. Wouldn't it be a hell of a lot easier if it was all in one place where each commit is globally consistent?
- _a_a_a_ 3y agoWord. BTDT, all services getting out of sync etc. Not worth it.
- tsss 3y agoNo one says you can't have all of your microservices use the same language...
- bob1029 3y agoAbsolutely. This is how we operated when we were at the peak of our tech showmanship phase. We had ~12 different services, all .NET 4.x the exact same way. This sounds like it could work, but then you start to wonder about how you'd get common code into those 12 services. Our answer at the time was nugets, but we operate in a sensitive domain with proprietary code, so public nuget services were a no go. So, we stood up our own goddamn nuget server just so we could distribute our own stuff to ourselves in the most complicated way possible. Even if you are using all the same language and patterns everywhere, it still will not spare you from all of the accidental complexity that otherwise becomes essential if you break the solution into arbitrary piles.
- ValtteriL 3y agoCan't you share them via shared libraries in .NET?
- jcmontx 3y agoYMMV but I think you can only do that if you have a monorepo with the shared library and all the microservices
- Atotalnoob 3y agoYou can, but it’s just kind of hinky, you end up relying on a specific path for the shared library
- deleted 3y ago[deleted]
- lmm 3y agoDoes .net not have a way to run simple private repository like Nexus? Over in JVM-land that's a basic thing that you'd be doing anyway.
- smaudet 3y agoIt's the difference between drag-dropping a reference between "projects" or whatnot in your monolith project, or coming up with a publish pipeline after which your merged code gets into the repo so that other people can use it, if you have three projects in three checkouts that all have to be coordinated and merged in order so that you don't accidentally break your environment and worry about security and and and.... One is much simpler than the other. Artifact management is surprisingly complex, it only looks like it works great while you aren't managing many versions and acting more like a monolith, just spread across repos/deploy points.
- lmm 3y ago> It's the difference between drag-dropping a reference between "projects" or whatnot in your monolith project, or coming up with a publish pipeline after which your merged code gets into the repo so that other people can use it You already have that pipeline for release/deployment though, don't you? (And it's already hooked up to your SSO or what have you). > if you have three projects in three checkouts that all have to be coordinated and merged in order so that you don't accidentally break your environment and worry about security and and and.... It's the same as any other library dependency though, which is a completely normal thing to deal with. The cost of separating your pieces enough that you can use different versions of a library in different services is that you can use different versions of a library in different services. I'm skeptical about microservices as a deployment model, but I'm absolutely convinced that code-level modularisation and independent release cycles for things that deploy independently are worthwhile, at least if your language ecosystem has decent dependency management.
- ljm 3y agoIdeally you would use the same language if it had distributed support. Use Erlang or Elixir for example and you have everything you need for IPC out of the box. Might take a little bit more effort if you're on Kubernetes. One of my problems with microservices isn't really the services themselves, but the insane amount of tooling that creeps in: GRPC, Kafka, custom JSON APIs, protobufs, etc. etc. and a lot of them exist in some form to communicate between services.
- tsss 3y agoIf you do so much IPC that you have to design your language around it you're probably doing it wrong. I don't think that moving to a monolith would really cut down that much on other technologies. Maybe you can do without Kafka, but certainly you will need some other kind of persistent message queue. You will still need API docs and E2E integration tests.
- jocaal 3y ago> If you do so much IPC that you have to design your language around it you're probably doing it wrong... I'm gonna have to disagree with this. Often when languages add features to their core, it allows for a very different (and often better) approach to writing code. Think Lisp with first class functions, or Rust with the borrow checker. Why should concurrency be any different? This feels like a Blub moment and I would highly recommend you give erlang or elixir a try, just to see what it is about.
- tsss 3y agoIf you need that much IPC then you aren't doing microservices correctly. Microservices are supposed to be independent, self-contained domains wherever possible. Purely technical boundaries like dedicated caching services that you see in very large companies like Google are more of an exception and should only be used when the non-functional requirements absolutely dictate it. A language that is designed around IPC wants to distribute dynamic parts of one application over multiple interchangeable compute resources (like in an HPC environment). This is a different thing altogether from microservices, which are self-contained applications working independently to each provide a fixed piece of the whole.
- switch007 3y agoYou need a CTO with a backbone to say no to the senior people hell bent on padding their resumes and scratching an itch though Too often devs weaponise micro services and say it’s one of the key reasons for microservices is to allow free language choice !
- superfrank 3y agoI think this is a false dichotomy. Most places I've worked with microservices had 2 or 3 approved languages for this reason (and others) and exceptions could be made by leadership if a team could show they had no other options. Microservices doesn't need to mean it's the wild west and every team can act without considering the larger org. There can and should be rules to keep a certain level of consistency across teams.
- orochimaaru 3y agoNot sure why you’re downvoted - but you’re right. We heavily use microservices but we have a well defined stack. Python/gunicorn/flask/mongodb with k8s. We run these on Kafka or rest api. We even runs jobs and corn jobs in k8s. Functional decomp is left to different teams. But the libraries for logging, a&a, various utilities etc are common. No microservices that don’t meet the stack unless they’re already developed/open source - eg open telemetry collectors. Edit: I think the article is a path to a book written by the author. It’s more of an advertisement than an actual assessment. At least that’s my take on it.
- ilyt 3y ago[dead]
- tcgv 3y ago> Most places I've worked with microservices had 2 or 3 approved languages for this reason (and others) and exceptions could be made by leadership if a team could show they had no other options. This works well if you have knowledge redundancy in your organization, i.e., multiple teams that are experienced in each programming language. This way, if one or more developers experienced in language 'A' quit, you can easily replace them by rearranging developers from other teams. In small companies, this flexibility of allowing multiple languages can result in a situation in which developers moving to other jobs or companies will leave a significant gap that can only be filled with recruiting (then onboarding), which takes much more time and will significantly impact the product development plan. More often than not, the choice between Microservices and Monoliths is more of a business decision than a technical one to make.
- cpill 3y ago> God forbid you find yourself with a need to rewrite one of these shitpiles. Actually, this is much easier with micro services as you have a clear interface you need to support and the code is not woven into the rest of the monolith like a French plat. The best code is the easiest to throw away and rewrite, because let's face it, the older the code is, the more hands it's been through, the worse it is, but more importantly the less motivated anyone is in maintaining it.
- lemmsjid 3y agoIf the monolithic application is written in a language with sufficient encapsulation and good tooling around multi-module projects, then you can indeed have well known and encapsulated interfaces within the monolith. Within the monolith itself you can create a DAG of enforced interfaces and dependencies that is logically identical to a set of services from different codebases. There are well known design issues in monoliths that can undermine this approach (the biggest one that comes to mind is favoring composition over inheritance, because that's how encapsulation can be most easily broken as messages flow across a single-application interfaces, but then I'd also throw in enforced immutability, and separating data from logic). It takes effort to keep a monolithic application set up this way, but IMHO the effort is far less than moving to and maintaining microservices. I think a problem is that there's very popular ecosystems that don't have particularly good tooling around this approach, Python being a major example--it can be done, but it's not smooth. To me the time when you pull the trigger on a different service+codebase should not be code complexity, because that can be best managed in one repo. It is when you need a different platform in your ecosystem (say your API is in Java and you need Python services so they can use X Y or Z packages as dependencies), or when you have enough people involved that multiple teams benefit from owning their own soup-to-nuts code-to-deployment ecosystem, or when, to your point, you have a chunk of code that the team doesn't or can't own/maintain and wants to slowly branch functionality away from.
- protomolecule 3y ago"composition over inheritance, because that's how encapsulation can be most easily broken as messages flow across a single-application interfaces, but then I'd also throw in enforced immutability, and separating data from logic" Could you elaborate on this? I see how "separating data from logic" is a problem but what about the other two?
- starttoaster 3y ago> Wouldn't it be a hell of a lot easier if it was all in one place where each commit is globally consistent? I always find this sentence to be a bit of a laugh. It's so commonly said (by either group of people with a dog in this fight) but seemingly so uncommonly thought of from the other group's perspective. People that prefer microservices say it's easier to change/rewrite code in a microservice because you have a clearly defined contract for how that service needs to operate and a much smaller codebase for the given service. The monolith crowd claims it's easier to change/rewrite code in a monolith because it's all one big pile of yarn and if you want to change out one strand of it, you just need to know each juncture where that strand weaves into other strands. Who is right? I sure don't know. Probably monoliths for tenured employees that have studied the codebase under a microscope for the past few years already, and microservices for everyone else.
- tklinglol 3y agoMy first gig out of school was a .net monolith with ~14 million lines of code; it's the best dev environment I've ever experienced, even as a newcomer who didn't have a mental map of the system. All the code was right there, all I had to do was embrace "go to definition" to find the answers to like 95% of my questions. I spend the majority of my time debugging distrubuted issues across microservices these days; I miss the simplicity of my monolith years :(
- iterateoften 3y agoNot so much a ball of yarn but more like the cabling coming out of a network cabinet. It can be bad and a big mess if you let it, but most professionals can organize things in such a way that maintenance isn’t that hard.
- starttoaster 3y agoWell, the point I was making was that the same can easily be true of microservice architectures. If you have people that don't know what they're doing architecting your microservices, you'll have a difficult time maintaining them without clear and strict service contracts. It's not clear to me that we're ever comparing apples to apples in these discussions. It would seem to me that everyone arguing left a job where they were doing X architecture the wrong way and now they only advocate for Y architecture online and in future shops.
- bibabaloo 3y agoHow many developers do you have working on that monolith though? The size of your binary isn't usually why teams start breaking up a monolith.
- haolez 3y agoThis sounds reasonable and correct, but my personal experience includes more monolithic messes than microservices ones.
- duncan-donuts 3y agoI was in a meeting to talk about our logging strategy at an old company that was starting micro services and experiencing this problem. In the meeting I half heartedly suggested we write the main lib in C and write a couple wrapper libs for the various languages we were using. At the time it felt kinda insane but in hindsight it probably would have been better than the logging mess we created for ourselves.
- anonymousDan 3y agoMaybe logging should be a microservice....
- Thaxll 3y agoWhy did you have 2-3 languages, does not make sense, I've been using microservice for a while and it was only one language at a time.
- deleted 3y ago[deleted]
- drzaiusx11 3y agoWe have 2 supported langs across our cloud teams and our core libraries are dual-lang'd where applicable; meaning they're both Ruby Gems and Pypi packages (Python3) in one repo with unified APIs and backed by a shared static config where applicable (capability definitions etc.) Each dual lib is released simultaneously with matching SemVer versions to our various artifactory instances & S3 buckets (for our lambda "layers"), automatically on every push to mainline by CI/CD. It works surprisingly well. We're evaluating a 3rd language but won't make that choice lightly (if it happens at all.) We have 14+ micro services, and it's fairly easy to "rewrite the shit pile" when you actually follow the micro designation. One of our services was originally in perl and we, quite mechanically, rewrote it in ruby in a sprint to align with our other services. Speaking from personal experience, when monoliths and the teams working on them get big enough, you start having "action at a distance" problems, where seemingly benign changes affect completely unrelated flows, often to catastrophic effect. You make an innocuous looking resource update in the monolith, like an update to a CSS stylesheet that fixes a bug in a flow your team owns, now breaks 10 others flows owned by teams you never heard of because they were using the existing structure for selenium tests or some js that now fails to traverse the dom because some order of selectors changed, etc. Microservices are as much a team organizational tool as they are a code one. The idea being those that work on the service "know it", and all it does. They can wrap their head around the whole thing. I think some orgs don't really get this point and _start_ with microservices, completely unnecessarily, for the stage they're at as a company. You always start with a monolith and if you get to the point where everyone is stepping on each other's toes from the lack of enforceable boundaries in the code, you do the obvious and start to create those boundaries. Microservices aren't the only way to do this of course. Any way of dividing up your service with enforceable contracts will work. Modules get designated with codeowners, assigned to various teams. Resources that were once shared get split up to align with the team structures better. Many frameworks allow multiple "apps" or distinct collections of APIs, so you can still ship your one-binary without splitting out the collections into different services. As soon as you have to independently scale one set of APIs but not another, you can state looking at service boundaries again. For the majority, that day will never come.