22 ms·
Microservices are hard
- jerf 4y agoNo, they aren't. The entire point of the big ball of mud is that there are no meaningful divisions in the code. Everything uses everything willy-nilly, at the smallest possible level of abstraction. There is, metaphorically if not always entirely literally, not a single line of code in the system that you can change without fear of bringing something else down that you may not have even known they existed. Microservices are not a miracle cure or the solution to every problem, but they do force divisions within the code base. Every microservice defines an interface for its input and its output. It may be the sloppiest, crappiest definition every, with dynamic types and ill-defined APIs and bizarre side effects, but it is some sort of definition, and that means if necessary, the entire microservice could be entirely replaced with some new chunk of code without affecting the rest of the system, cleanly cut along the API lines. This microservice may sloppily call dozens of others, but that can be seen and replicated. It may be called by a sloppy combination of other services, but the incoming API could be replicated. However bad the architecture of the microservice may be, however bad the overall architecture of the microservice-based system as a whole may be, this will be true by structural necessity. The network layer defines some sort of module. They can create big balls of spaghetti, certainly. They can in total create a big mess; they are not magical architectural magic by any means. While a full replacement of a given microservice is practical and possible, if the boundaries are not drawn correctly to start with, fixing that can be much harder in a microservice architecture (with corresponding separation of teams) than a monolith. But they fail to create the situation that is what I would consider the distinguishing characteristic of a "Big Ball of Mud", where there are no partitions between anything at all. Big Balls of Mud have no equivalent of "replace this microservice". Microservices by necessity, to be "microservices", have partitions.
- jasonhansel 4y ago> if the boundaries are not drawn correctly to start with, fixing that can be much harder in a microservice architecture (with corresponding separation of teams) than a monolith. Therein lies the problem. Nobody draws these boundaries correctly on the first try, and the correct boundaries can shift rapidly over time as new features are added or requirements change.
- nprateem 4y agoThe main reason is to stop crap developers using globals all over the place, or passing around hash maps stuffed full of config that aren't clearly defined in one place just continually mutated (and similar bad issues). Still, crap devs will just find their own ways to mess up with microservices, but at least they limit the blast radius.
- HardlyCurious 4y agoThey limit the blast radius to the scope of systems that either directly or indirectly call the microservice, which is commonly the same blast radius as a monolith that was replaced by the microservices.
- esailija 4y ago> It may be the sloppiest, crappiest definition every, with dynamic types Funny you said that since a microservice API is always dynamically typed and its usage cannot be checked by compiler. And the more microservices you use the more dynamically typed the whole project gets overall. While you can opt into a free for all everything importing everything, all languages do also support creating modules which define APIs for consumer and maintain compile time type checking.
- okamiueru 4y agoAlthough true to some extent, this is also a tooling issue. We use OpenAPI and generate clients. Strictly speaking the interoperability layer doesn't know the truth on the other side, but when generated correctly, the developer doesn't need to worry about it.
- esailija 4y agoWhen you change function signature it doesn't compile until you fix all the call sites. Maybe after you see all the broken call sites you think that's too much work maybe there is some other way to do what I want. When you change anything about an endpoint, it compiles just fine no matter what clients there are or what they are doing. You proceed with the change without worry. Yes, you can have some self-discipline to also generate the open api documents, generate the clients and then check all clients but self-discipline like that is not reliable. So while tooling can help it's still not the same thing.
- com2kid 4y ago> When you change function signature it doesn't compile until you fix all the call sites. Maybe after you see all the broken call sites you think that's too much work maybe there is some other way to do what I want. Improperly versioned dynamic libraries want a word with you! Perfectly possible to foot gun yourself with compiled code and broken API boundaries. > When you change anything about an endpoint, it compiles just fine no matter what clients there are or what they are doing. If I am exporting a DLL, same thing happens. Working on a true monolith, the entire app is compiled as one giant executable, sure, then I get compile errors.
- naasking 4y ago> No, they aren't. The entire point of the big ball of mud is that there are no meaningful divisions in the code. Everything uses everything willy-nilly, at the smallest possible level of abstraction. There is, metaphorically if not always entirely literally, not a single line of code in the system that you can change without fear of bringing something else down that you may not have even known they existed. This is bit of a strawman. The equivalent strawman criticism for microservices is that every function runs in its own networked service. Is that truly representative of the reality? Of course not, and neither is your breakdown of big ball of mud. I think this is a fair analysis of the BBOM: http://www.laputan.org/mud/mud.html http://www.laputan.org/mud/mud.html
- jerf 4y agoFunny, I was thinking of linking to that page myself in support and decided against it. I particularly was thinking of: "What does this muddy code look like to the programmers in the trenches who must confront it? Data structures may be haphazardly constructed, or even next to non-existent. Everything talks to everything else. Every shred of important state data may be global. There are those who might construe this as a sort of blackboard approach [Buschmann 1996], but it more closely resembles a grab bag of undifferentiated state. Where state information is compartmentalized, it may be passed promiscuously about though Byzantine back channels that circumvent the system's original structure." and "Such code can become a personal fiefdom, since the author care barely understand it anymore, and no one else can come close. Once simple repairs become all day affairs, as the code turns to mud. It becomes increasingly difficult for management to tell how long such repairs ought to take. Simple objectives turn into trench warfare. Everyone becomes resigned to a turgid pace. Some even come to prefer it, hiding in their cozy foxholes, and making their two line-per-day repairs." Superficially it may seem like these criticisms apply, but they don't. Microservice architectures can't have big global variables typing things together, structurally. Even if "everything talks to everything" (which is actually unlikely, sarcasm aside, even the absolute worst systems have more structure than that in a microservice architecture), it does it through a defined mechanism of RPC. State can't be passed through "back channels" because no back channels exist; you must go over the network, which is the "front" channel, not a back channel. By structural necessity, a microservice confines the scope of changes in the microservice code itself. There are then of course still scopes of changes that are even harder with microservices at the global level, but for refactorings that aren't behavior changes a microservice necessarily confines the scope of changes to the microservice itself, a small fraction of the whole. As long as the API accepts the same input and returns the same output, it can not blow up another service three layers away because it has no access. But that's a distinguishing characteristic of a Big Ball of Mud. Big Ball of Mud isn't just a slur; it's a distinct pattern as described in that paper. At best a microservice architecture can be a lot of smaller "balls of mud" hooked together, and that's still a problem, but it is its own problem. This is proved by the fact that the solution to a Big Ball of Mud won't work for an microservices architecture disaster... indeed, they aren't even sensible. If two problems require separate solutions and the solution to one is not even conceivably applicable to the other (that is, not even a "bad" solution but simply no solution at all), they are clearly not the same problem.
- dagss 4y agoOk, so if this is where you come from: "The entire point of the big ball of mud is that there are no meaningful divisions in the code.... Everything uses everything willy-nilly....not a single line of code in the system that you can change without fear of bringing something else down that you may not have even known they existed" ...then OK, perhaps the developers who caused the state you describe above would not cause the exact same problems with microservices -- but will they really move fast any not cause a mess given ANY kind of environment? The state you describe is not normal of monoliths by any stretch. It may be normal of old legacy systems with 5 generations of programmers on it. Also I believe microservices will have other kind of problems, but still deep problems, after 5 generations of programmers. If preventing people from running in the completely wrong direction of the goal is your main concern -- why even be in the race at that point. Find new people to work with. If you personally had success rewriting a Ball of Mud into microservices, consider if perhaps the "rewrite" is the important word (as well as quality of developers involved), not whetyer the refactor was to a new monolith or new microservices. Microservices with boundaries drawn wrong can cause you to need to spend 20 programmers do the job of 1 programmer. Perhaps the mud looks different from a Big Ball, but it is still mud.
- drewcoo 4y ago> Microservices are not a miracle cure or the solution to every problem, but they do force divisions within the code base. Do they? The code itself may be in entirely separate repos but still be tightly coupled. Monoliths can have cleanly separated libraries/modules, those modules built from separate repos or at the very least, different namespaces. The "macroservices" I've been seeing are many separate containers all sharing at least one data store. So they have all of the disadvantage of the "ball of mud" monolith combined with all of the disadvantage of much more complicated infrastructure. Yet the people working on them think they're "doing microservices" because k8! The microservice separation is not just code in separate repos. It's also everything else behind the kimono - keep that kimono clasped tightly!
- BulgarianIdiot 4y agoI just sit back, sipping coffee and chuckle. We went from "services should be no more than 100 lines of code" to "testing and maintaining thousands of interconnected microservices is TERRIBLE IT TURNS OUT". The secret here is that all simple answers are wrong. Your services are too small and too big at the same time. Finding balance is hard. Zen Buddhists call it the "Middle Way". The best design is always an uneasy intersection of many approaches and concerns, and also it's the concept of what you decide NOT to do, so you have more resource to focus on what TO DO. Also we keep overanalyzing how we do services in isolation, when the complexity comes not from each of them alone, but how they interact. To solve this complexity you need clear, aligned flows. More like laminar flow. Less like turbulence.
- JAlexoid 4y agoToo many microservice advocates argue about the simplicity of their precious tiny codebase, meanwhile there is always a gigantic ball of mud that does all of the orchestration... and most often very badly.
- bayesian_horse 4y agoMaybe the only good reason to use a microservice is so you don't need to build and maintain it yourself. Databases are microservices, S3, Keycloak, Sentry, all sorts of stuff. Also goes for other teams in your company building and maintaining the service.
- imankulov 4y agoIn my experience, the "Citadel pattern" is a good alternative to microservices for small to medium teams. I have seen it emerged as a natural evolution of a monolith in several places where I worked, where it served us well. https://m.signalvnoise.com/the-majestic-monolith-can-become-the-citadel/ https://m.signalvnoise.com/the-majestic-monolith-can-become-...
- bobleeswagger 4y agoIf your microservices are hard to test you've designed shitty microservices. Period.
- JAlexoid 4y agoYou microservice can be easily tested. But then you may end up with - is your whole system testable and how do you do good integration tests? Right now I work in a pure microservice architecture, where there are no proper system or integration tests. And we had minor bug fixes break things spectacularly.
- bobleeswagger 4y agoSounds like your CTO and engineering leadership aren't owning the architectural issues that are preventing integration tests. I'm not saying it's easy, but there's a point where there are no excuses allowed from the owners.
- waselighis 4y agoAll of these articles against microservices are so annoying because I rarely see a good argument against microservices. Often the arguments are purely anecdotal and without substance. There are only two good arguments I can make against microservices. First, it's not the right architecture choice for all projects. Second, microservices don't magically solve the problem of complexity. But I can name countless benefits of a microservices architecture. Individual microservices are far less complex than monoliths, which allows even a single developer to work on a microservice, run and test it on their local machine, whereas monoliths may require dedicated test servers because they're too large and complex to run on a developer's machine. Microservices simply dependencies because each microservice has exactly the dependencies it needs, as opposed to a monolith that becomes a huge tangled mess of dependencies locked to specific versions, and incredibly complex environments to ensure all these dependencies don't interfere with one another, where any little change or misconfiguration will bring down the entire service. Microservices allow for more rapid development, since you're only rebuilding and testing a small part of the entire architecture, without interfering with others work, allowing many independent teams and individual developers to work in parallel. Without elaborating too much, I'll reiterate what is said many times over, microservices are generally easier to scale horizontally with less downtime. A common misconception I see is microservices have to be simple and tiny. But your database system can be considered a microservice, and that's hardly simple or tiny. The point is the database serves a single purpose in the overall architecture of the application, and it can be managed independently of all the other microservices. What you shouldn't do is, say, combine your database and message broker into a single microservice. Yes, microservices are hard, and there's so many ways to do it wrong. But you know what? Software Engineering is a hard problem in general, and it's unlikely there's ever going to be a great solution that magically solves all our problems, only incremental improvements that allow us to manage ever greater complexity.
- JAlexoid 4y agoThe argument against microservices is simple - there should be a clear use case for a microservice. Don't go - "we do everything as a microservice". Almost 20 years ago we had "we do everything using SOA"... Same thing. And your own comment shows that microservice advocacy are inconsistent: > Individual microservices are far less complex than monoliths, which allows even a single developer to work on a microservice, run and test it on their local machine > database system can be considered a microservice, and that's hardly simple or tiny DBMS is as much a microservice, as many other microservices are. You cannot just replace a DBMS with another transparently, just like in many cases you cannot just deploy a different version of a microservice without coordination.
- mgaunard 4y agoThere is nothing about microservices that require them to be distributed over the network, it's just something that they enable. Most of the pain points I hear about microservices are to do with versioning and deploying them independently. But again, this is just enhanced flexibility, you don't have to use it.
- DavorDK 4y agoTrying to keep it simple (to a degree). First of all, I would say that its OK to still have a monolith and even build a whole product as a monolith and break it down as the need for microservices arises. My understanding of whether or not you should take a monolith and cut it into pieces is that it depends on what you want to achieve. Every monolith is specific, or are they? Without knowing what your product does I bet you have an API, a UI layer or two, some business logic and maybe throw emailing or a payment service. Well, guess what? We all have those! How to decide. For myself, I’ve tried to boil it down to 3 questions: 1. Will I need to scale this part of the monolith more (often) than others? 2. Does this part of the monolith handle an entire process on its own from start to finish? 3. Does this part of the monolith require a lot of different code or resources than the other parts? The questions are simple. They aren't philosophical. They don’t have a hidden meaning. Rather, a series of simple booleans. If something needs to be a microservice it'll most likely hit 3 out of 3 of those.
- robswc 4y agoWorked on both monoliths and micro services. I'd rather work on a good monolith than a bad microservice and vice versa. The problem is, working on a bad monolith is almost impossible. I'd rather work on a bad microservice than a bad monolith. Now... tbh this could be survivorship bias where I've never had to help with a well-running monolith, fair... but at the end of the day, I find microservices much easier to manage scope, change and scale.
- marcosdumay 4y ago> I'd rather work on a bad microservice than a bad monolith. That's not the choice. The choice is between a bad monolith or a bad microservices ecosystem. And the microservices tend to come with organizational policies too, that may or may not allow you to access, see, or change some subset of them.
- sisve 4y agoI really do not understand the debate on monoliths and microservice anymore. Context matters so much. Should you have absolutely everything in 1 system. No. And I think no one thinks that anymore. Should you spilt your system into as many pieces as possible? No, of course not. You are prop. storing files one place and have a data in a database another place. And most likely none are on the webserver receiving request. Or maybe you are, because context matters and I'm wrong in your particular case. Could be. My advice would be to split your application up into enough pices so that; 1.your engineers feels like they have control over the code and are not afraid of doing changes. 2. if you get uptime issues. Get the heavy / unrealiable services over to new node. Don't let one service/endpoint take down other endpoints. Think and act according to the problems you have in front of you. Don't go extreme in any direction. Context context context
- chucksta 4y ago>Context matters so much. Well that point that just makes %90 of web articles moot.
- avip 4y agoLike any other well reasoned, balanced and pragmatic POV, the problem with your boring approach is you can’t wrap it in a clickbaitable blog and no flame war can emerge from it.
- hinkley 4y agoIn no public debate do you get the participation of people who think everyone involved is a lunatic. We presume there are two extremes in any decision making process and ignore the third option, no matter how reasonable.
- username135 4y agolol
- nullsense 4y agoIt turns out the One Weird Trick is just considering the context.
- _ea1k 4y agoI've been on both sides of this debate. I've seen codebases from teams that want monorepos and macroservices that fit all of the falling criteria: - The codebase had three primary responsibilities - None of those functions overlapped in functionality and didn't share any significant code - They were all written by different people with subtly different styles - They used infrastructure code for talking to third party services in subtly different ways that made upgrading dependencies difficult In theory, they were all within the same business domain, so the types that think one business domain equals one service clumped them together. This made little sense. On the opposite side, I've seen microservices where all the little services depended on one another in complicated ways that made them all a brittle mess. Finding the right solution to each problem is always the real challenge.
- 0x445442 4y agoThere are a few gripes I have with microservices. I think most places rearchitect to microservices because it’s the new shiny. They don’t do the engineering necessary to create a detailed cost/benefit analysis, they just feel it will be better and so they jump in. For the same reasons the companies don’t do the cost/benefit analysis they don’t spend much time thinking about how they could benefit from rearchitecting their monolith into various libraries, modules, packages and interfaces. Because they don’t think much about these code boundaries, they end up turning their monolith into a distributed monolith. In doing so they don’t get the major benefits microservices are meant to provide, such as independent code deployment. They also lose the benefits of a monolith, such as less ancillary complexity. This situation is the norm and is evidenced by “deployment parties” where you can’t just deploy one microservice because 11 of them need to go to prod together. What I have seen a lot of over the past few years is a push to get off main frames and into the cloud. This is a valid driver for rearchitecting but microservices are just one of a number of solutions as the cloud is very flexible these days. I assert that a lot of rearchitecting to microservices can be attributed to the fact that our industry, as Alan Kay has said, is a Cargo Cult.
- nerdix 4y agoIn my experience, most places rearchitect to microservices because they have a shitty monolith that they are dealing with. The monolith has been built over a span of 10+ years. It is fragile, brittle, no one understands how the whole thing works, and large scale refactoring without widespread breakage is near impossible. No one wants to touch it because no one understands how the whole thing works. Because of this the codebase is also falling behind and isn't staying current with language updates (I know everyone here likes working with 10 year old tech but it does affect hiring when you have to say that you're using Java 8) But it is true that distributed monoliths are very common. One problem is that it's hard to get everyone on board with going "all the way". The question "Do we really need multiple databases" is one of the main culprits that spawn distributed monoliths.
- 0x445442 4y ago> The question "Do we really need multiple databases" is one of the main culprits that spawn distributed monoliths. It's true the lack of bounded contexts is a big problem. But I also see a lot of orchestration services with multiple dependencies on other services, some of which are themselves orchestration services. This quickly cascades into dependency hell only you don't get the benefit of a compiler to alert you to the problems.
- cs702 4y ago...and if you've had a team of developers eagerly using microservices for pretty much everything in production code for any significant period of time, microservices become like a big ball of mud held together by a lot of hair. I shudder in horror when I think about how impossible it will be to maintain all that code in the future.
- bob1029 4y agoI've found the nuance is in the middle somewhere. We've all seen the madness with web scale infrastructure for a personal blog, but one gigantic compilation unit will eventually bite you in the ass too (i.e. rebuilds get very slow). What you probably want is something where everything lives in the same repository, but as separate modules/dlls which can be included in some common execution framework the team previously agreed upon. If you have something approximating microservices-as-dlls, then you are essentially eating cake while having cake when you really think about it. Function calls are still direct (sometimes even inlined), but you could quickly take that same DLL and wrap it with a web server and put it on its own box if needed. Establishing clear compilation unit boundaries without involving network calls is the best path for us, and I suspect it's the best path for anyone to start with. We take this "don't involve the network" philosophy into our persistence layer too. SQLite is much easier to manage compared to the alternatives.
- alanfranz 4y agoMicroservices can be useful when a single team can’t handle a service anymore. You should have as few services as possible, not as many as possible (eg see team Topologies) Otherwise, use modules, or package by feature, to prevent the big ball of mud problem. That’s useful within a service as well.
- pier25 4y agoUse the best tool for the job. It's stupid to think of monoliths vs microservices. You can use both if the problem requires it. For example I'm currently working on an audio hosting service. The main app is a monolith where 90% of the code resides but there are a couple of ancillary services. Audio encoding (which is heavily CPU bound) is a serverless microservice that can scale up and down as needed. Users don't upload content constantly, but when they do, you want to be able to encode stuff concurrently without blocking the main app. Audio streaming is also a serverless microservice because hey for every user uploading content you can have 1000x consumers (or more).
- ricardobeat 4y agoThis argument is brought forth a lot, but it misses the point. Often people think microservices are the right tool for the job, but they vastly underestimate the complexity that it entails.
- mdaniel 4y ago> Often people think microservices are the right tool for the job, but they vastly underestimate the complexity that it entails. And that goes 10x if deploying, monitoring, or debugging said services is Someone Else's Problem ™ I'm also cognizant that such a situation is just as much an organizational/people problem as the rest of this debate, but I have a sore spot around people making decisions where they don't have to suffer the consequences from them
- pier25 4y agoIf you can solve a problem without a microservice then probably it's not the right tool for the job.
- candybar 4y agoI think your position is basically the same position that most people that advocate for monoliths (which btw is a bit of a strawman created by microservice architecture advocates in the first place) hold. People are objecting to service/network boundaries as a default domain decomposition tool and arguing that it should be used instead when there are clear and immediate technical advantages to do so.
- ricardobeat 4y agoTitle has been editorialized? The original post is "Microservices are a Big Ball of Mud".
- idealmedtech 4y ago> At the point in time when you slice the domains you might not know all the product requirements. Probably a feature will arise which forces you to tangle two services together - now you have one domain. But distributed. Urgs. Are there any architectures which would allow you to monolithize services like this? Changing product requirements sometimes mean you've just arrived at a better abstraction, which may need you to combine services directly.
- no_circuit 4y agoI think the key point in the article is the conclusion: try building things more as modules that can be easily split off into separately running server applications as needed later. So in practice that could look like the interface to your "module" should use parameter objects [1] for function calls, and build in the assumption that most information retrieval or processing requests are async. Then when the time comes swap out the local version of the module of the client stub version. To avoid manually writing the serialization, those parameter objects should have been code generated already. Although the goals of something like tRPC [2] are admirable, having to manually check inputs with typeof [3] honestly shouldn't be necessary. And allowing non-nullable fields may make field deprecation extremely difficult or impossible. Guess what? If you have any native mobile clients they may not upgrade for years! OpenAPI also exists, but seems a bit too verbose to read, or author manually. So what would I suggest? Just use proto3/gRPC [4]. It defines the JSON encoding if you haven't clients that can't talk native Protobuf, or don't want to have bikeshedding over what type-casing to use for JSON serialization. If your cloud provider doesn't do it for you already, just drop an Envoy with the gRPC-JSON transcoder in front [5]. If you can't prove you'd have an actual performance problem due to gRPC/Protobuf, then it probably isn't worth the effort to use a less battle-tested messaging library. So back to the main topic... it doesn't have to be hard to do microservices when the time comes, just make sure your codebase is easier to convert. [1] https://wiki.c2.com/?ParameterObject https://wiki.c2.com/?ParameterObject [2] https://trpc.io/ https://trpc.io/ [3] https://trpc.io/docs/quickstart#add-a-mutation-procedure https://trpc.io/docs/quickstart#add-a-mutation-procedure [4] https://developers.google.com/protocol-buffers/docs/proto3#json https://developers.google.com/protocol-buffers/docs/proto3#j... [5] https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter https://www.envoyproxy.io/docs/envoy/latest/configuration/ht...
- athenot 4y agoThe discussion of Microservices vs. Monolith feels a lot like NoSQL vs. Relational one. That is to say, Microservices are a bad idea right up to the point where monoliths won't work. Most services can be successfully implemented with monoliths (and relational DBs for that matter). Only when that solution doesn't scale anymore, that's when microservices come in handy. Particularly when a large service has core functionality that must always run and secondary functionality that can tolerate higher rates of failure.
- randomdata 4y agoFacebook is a monolith backed by a relational database. What scaling problems do you have that they don't have?
- api 4y agoI am so, so tired of the "is hard" cliche. It's at gag response level for me. Am I the only one? Writing meaningful titles is hard.
- hintymad 4y ago> Large companies like Uber learned this the hard way: Uber is really not a good example. Many Uber engineers created services for the sake for claiming their territories or for sheer stupidity. On the other hand, managing services in Netflix was a non-event, and people really exercised their judgement carefully when it came to creating a new service. Yeah, I'm saying Uber's problem was cultural and organizational, not technical.
- JAlexoid 4y ago> Yeah, I'm saying Uber's problem was cultural and organizational, not technical. That's the issue currently with microservice architecture zealots - microservices for the sake of microservices.
- deleted 4y ago[deleted]
- John23832 4y agoStart with a monolith, that will take you VERY far. When the organization gets big enough (AND ONLY THEN), add an additional domain oriented service. FULLY implement deployment and infra. Only once you do that can you think about adding another (using the pattern you just built out). Micro-monoliths. Organizations explode the number of services, half ass the infrastructure (the hard part of microservices), and then crumble under the organizational complexity.
- hot_gril 4y agoMy org did this, and it ended in disaster because that monolith was shoving everything in the world into a single database the whole time. This created horrible APIs: one team writing into tables that another team is expected to read. They tried to split this later on and created an even bigger mess. There are reasonable places before then to stop and say, we need to keep X new features in a separate service.
- John23832 4y agoThat’s still not a microservices vs monolith problem. That’s a bad data stewardship problem. If your data is a mess before you decided to break out functionality, then it’s gonna be hard regardless. You should have good schemas and db organization always.
- hot_gril 4y agoThis issue is about microservices because the one alternative to this DB-level data sharing is having proper RPCs (or more specialized things like pubsub in some cases) between cleanly separated services. If logically separate things are sharing data through the DB itself, you will get a mess even if you're very careful, which they were.
- John23832 4y agoYou should have a well curated DB regardless of whether one or many domain specific services sit in front of it. That is what would enable you to break a monolith up. Good code and architecture is the result of discipline. Your data is your most valuable asset. What you're describing is a mess. You mentioned RPC's. Your service interface has nothing to do with the data organization. But if you think microservices is what would work for you, then you should pursue that next time. My original post was a path to a multiple service architecture that approached service expansion with technical rhyme and reason. It really wasn't aimed at your organizations messy database.
- bradwood 4y agoHaving run k8s and _classical_ microservices before, I am now in a much happier place just using the AWS serverless suite (lambda, API GW, CF, SNS, SQS, eventbridge, dynamodb, etc). Is my setup "microservices"? Well, maybe, depending on your definition, but, in truth I don't really care - it works pretty well. We also do "DDD" with it and have multiple AWS accounts with these marking the domain borders. Comms between the accounts is via eventbridge or (very rarely) inter-account API invocation. This allows many of the benefits of microservices, without the pain of dealing with k8s. Clean separation of domains, reduced cognitive loads for teams, each of which looks after all the stuff in a single account (so-called feature teams, where each team designs/manages and runs everything in that account/domain). The hard bit was defining the domain borders, and the inter-domain protocols/interactions, but, once this is well defined, things work pretty well. Having come from a k8s world, this setup feels so much nicer, and lighter, and easier to get stuff built in a both fast and performant way. It would be interesting to see trends away from _classical_ "cloud-native" (k8s) setups with microservices, to true serverless setups. I wonder how much of k8s's lunch serverless has managed to eat so far.
- bradwood 4y agoit's also worth noting that, initially, we built everything in one account, and had 1 team doing all of it -- the cognitive load became too high at one point, and, only then, did we break out the "DDD" and split the concerns across many teams.
- dagss 4y agoWe were really happy with Google App Engine for the same reason. It's a product that feels like it was "10 years too early". Like you I feel the whole microservice debate turns into a "depending on definition" kind of thing and feels odd. Write stateless code that can infinitely scale -- is it 1 or 100 services? Just depends on the perspective really...
- DanielBMarkham 4y agoI keep reading these microservice essays where the author is lost and I really feel their pain. In that spirit, let me try to make things as simple as possible. (True) Microservices have no dependencies on anything but unstructured text data. They do not couple to a database, the business understanding of what it's doing, a domain model, or anything else. They perform a simple, idempotent, business task that can never fail although it can create various error chains. Programming at scale is tough. There's no free ride here. All you've done is turn the traditional model of coding "inside-out" and now you've got a ton of work doing all of the wiring. But if you keep your microservice doing one simple useful business thing, then all of that inside-out work become business decisions. What do we do if the sign-up fails? How do we move IMPORTANT-THING to those other guys to use? You still have business coupling: things change and you have to adapt. But you're not coupled at the _coding_ level. If there's any magic, that's it. Your business should be able to wander all over the place and your microservices hold up just fine. The old way, where we may have coupled every little business need or want with every piece of code in the system, was not only a pain, more importantly it was impossible to keep organized in any one person's head and aligned with everyone else at scale. What I see is a lot of drift. Folks start coupling things up, perhaps by trying to create one domain model to rule them all. They start creating microservices to do _system_ activities, like flushing a cache. There should be a one-to-one correspondence between your microservices and interesting business conversations. That's a hella discipline to maintain. It may force a lot of conversations you thought you could avoid by hiding them in a class hierarchy somewhere. Once you start drifting, pretty soon you're writing essays like this. And then here we are/
- XCabbage 4y agoThis doesn't make much sense. "Interesting business conversations" should map 1-to-1 with microservices but also each microservice must perform a "simple, idempotent business task" but also microservices can't be coupled to a database? Okay, enjoy developing your business with no data persistence whatsoever and where your architectural principles forbid you from ever so much as sending an email.
- ndrake 4y agohttps://www.youtube.com/watch?v=y8OnoxKotPQ https://www.youtube.com/watch?v=y8OnoxKotPQ
- hcarvalhoalves 4y agoMicroservices are analogous to classes from OOP: an attempt at modularization by bundling function, internal state and side-effects together. So it suffers from the same challenges. It’s worse in fact, as the message passing now involves unreliable I/O, and the internal state is also shared global state. The main reason it exists is because of the availability of cheap commodity hardware for servers (and later cloud), which breaks the model of programming for vertical scaling afforded by the mainframe model. It’s out of necessity to scale cheaply that this architecture is followed - the rationalizations that this is a superior way for teams to work together or that it improves reliability can be argued.
- UltraViolence 4y agoMicroservices suck and I hate the IT world for hyping it and jumping on the bandwagon to nowhere. We never should've gone with this. It makes things ridiculously difficult with almost no benefit. Just stay with the trusty old Monolith!
- dkarl 4y agoThis article doesn't provide any insight into when monoliths might be a better choice than microservices. It just says that if you do microservices you'll make awful mistakes and end up with a bad result. The word "macroservices" sort of sums up the whole conversation to me. People are so convinced that microservices can't be done right that when they start to do microservices right, they think they need to invent a new name for it. Everything that can be done successfully can also be done poorly and unsuccessfully. What's the word for walking successfully? Walking. Can you imagine what babies would say about walking if they could blog? "Walking is an extremely popular and hyped activity that has achieved an impressive amount of mindshare in the past several months. Caregivers appear to be highly invested in walking as a key to unlock unprecedented mobility. However, if you look past the hype to the reality, walking is mostly about falling down, hitting your head, running into things, and crying because you suddenly realized you can't see your caregiver. At DoodooHeadCorp, we have developed a new approach that delivers on the promise of walking, without miring you in all of its failures. We call it realwalking. Realwalking consists of moving from place to place while propelling yourself forward in a dynamically balanced bipedal fashion. Note that by definition realwalking involves moving from place to place, a crucial distinction that guides you away from one of the biggest pitfalls (no pun intended) of walking. Traditional approaches to walking have often resulted in babies standing up and immediately falling backwards into the same place where they started. Horizontal displacement is crucial and too often ignored by babies who have gone down the rabbit hole of walking. This is where realwalking innovates, by leveraging the power of dynamically balanced bipedalism." Just freakin' say it's hard, you should be prepared to learn along the way, and at every moment your ambitions should be scoped to your capabilities. There's no alternative that can claim differently. The factors you should consider when considering whether you will be successful with microservices seem to be outside the scope of this blog post, so I won't address them either.
- aeschinder 4y agoMicroservices are excellent when you have a self-contained set of APIs that need to be updated independently of other code. You must adhere to a contract, publish the contract and provide backwards compatibility for all existing clients. Perfect example is a Payment Service. You have API tiers, client tiers, backend service tiers and likely customer service tiers hitting it and getting payment histories, issuing refunds, and hopefully requesting payment transactions. This code will likely change constantly and you want to deploy it on your own schedule versus having to match the schedules of all of the clients. Other candidates might be an image upload service that crops, resizes and creates copies for CDN origin calls or a fraud scanning API that scores text submissions. You definitely want to keep the number of microservices SMALL. At some threshold the number of services becomes unmanageable because you have to support all the old interface versions.
- aryehof 4y agoOf course they are hard. Instead of a well modularized application where applicable, lets create multiple distributed programs that need to communicate across an unreliable network. Why? Because its fashionable, others are doing it, its a safe answer in an interview, its a buzzword (like “agile”) that management loves, and it seems that the only way many can introduce modularity is by making each module a separate program.
- gloosx 4y agoSomeone tell this boy K8S EXISTS! My Ingress yaml uses just 50 lines to slice all domains i need, not hard at all. Even if i don't know what to build or do i can spin up ping-pong micro-services in minutes just to let em play and have fun. All this complexity is abstracted to neat things now, like Ingresses, Services, Deployments and so on.
- nokya 4y agoWhat a waste of time. Anyone who's not an architect or developer, but regularly works with architects and developers, intuitively reaches these conclusions. And this has been going on and on for almost ten years. When you watch this from the outside (e.g., let's say, as a consultant called to advise on a very specific aspect of software architectures) it feels like they all follow a secret agreement that instructs them to go full microservices route. Questioning this, even as a consultant paid to do exactly that, is considered unacceptable. It's like questioning your client's religious or political beliefs. I observe a similar trend with CIOs hired to help institutions digitally transform themselves. Many operate on an "innovative" reasoning that consists in going full cloud and lay off IT personnel, which inevitably leads to increased operating and maintenance costs without exploiting the actual benefits of cloud computing. But it's already too late, Mr/Mrs CIO has already left the org when this happens. And self-congratulating words are already published in their LinkedIn profile. I often have two thoughts when I attend a pre-sales meeting with a prospect customer that shows us a beautiful microservices architecture: 1. Oh my... 2. Shut up and just take the money they are throwing at your face.
- abunuwas 4y agoIf you can't get your monolith right you probably won't get your microservices right. Microservices do come with additional overhead in terms of infrastructure, integrations, and so on. There's a concept of microservices readiness (e.g. https://learn.microsoft.com/en-us/azure/architecture/guide/technology-choices/microservices-assessment https://learn.microsoft.com/en-us/azure/architecture/guide/t...). Many organisations aren't ready to embrace microservices, and if they get into microservices before they're ready, then it's a lot of pain. There's also this misconception that microservices must be nano-services. But that's not a problem with microservices architecture, it's a problem of using microservices anti-patterns. As with everything in technology, there's no universally unique solution to all problems - everything's context-specific.
- mainguy 4y agoOr as I like to say "Oh, you have a big ball of mud in your monolith because of poor design and want to move to micro-services?"..."now you have n^n big balls of mud" Poor design is poor design, adding more complexity just makes it a more complicated poor design.
- api 4y agoAll these design pattern and methodology fads are attempts to get around the simple truth you stated, and one other: No design pattern or methodology will make bad programmers write good code. The only solution for poor skills is practice, education, and experience.
- deleted 4y ago[deleted]
- rqtwteye 4y agoYup. I always tell people that if they can’t write and manage decent libraries microservices won’t help them.
- PaulHoule 4y agoI'd say it doesn't have to be. There is a certain kind of "freedom" that is really slavery, but people feel so free when they hear about it is they often squee and hurt themselves with uncontrolled movements. Microservices can be that way. Now that you have 25 different services in 25 different address spaces you can write them in 11 different languages and even use 4 versions of Python and 3 versions of Java. (I got driven nuts years ago in a system that had some Java 6 processes and some Java 7 processes and it turned out the XML serialization worked very differently in those versions.) If you want to be productive with microservices you have to do the opposite: you have to standardize build, deployment, configuration, serialization, logging, and many "little" things that are essential but secondary to the application. If a coder working on service #17 has to learn a large number of details to write correct code they are always going to be complaining they are dealing with a "large ball of mud". If those little things are standardized you can jump to service #3 or #7 and not have it be a research project to figure out "how do i log a message?"
- PlumpyGER 4y agoThe problem with standardizing these things is, that it makes them hard to change. A breaking change in the way you deploy must also work for all other solutions - otherwise you immediately loose your standardization. And this will happen eventually. For all this different kind of problems it is near impossible to avoid inconsistency and force rules on them. So, imo you either have a (very) large organization with independent teams that work on independent services and give them the freedom for everything - or you develop a proper modulized monolithic software and extract services only as a last resort. I would avoid to use a microservice architecture with a small team of developers
- nostrebored 4y agoNo, standardizing these things makes them hard to change for devops. How many breaking deployment changes have you seen in reality? You're right that microservices shift burden onto infra. But that does not make it a big ball of mud -- infra has gotten progressively easier over the past two decades. If you want me to create the 'ball of infra mud' mentioned in your article, I can do it -- and make it repeatable -- in a few hours. It will come with dashboarding out of the box. This is why microservices have become more appealing to more businesses. The technology allowing you to provision this infrastructure and deploy your code has changed immensely, allowing you to shift some of that burden over to infra. People don't need to be given freedom for everything. Like the parent mentioned, with this standardization, people writing application code are able to move quickly and understand how the pieces work under the hood without shifting their mental model.
- rahoulb 4y agoI think the problem with microservices is the same as the problem with OO programming (and I say this as a pure OO Rubyist) ... what you are doing is shifting the complexity out of your code, where at least it's under source control and (hopefully) readable. And moving it into the order and timing of the interactions between your services/objects - which isn't readable unless you start hunting through log files.
- manojlds 4y agoAnd then you invent things like service mesh, tracing and what no to solve the problem you created.
- randomdata 4y agoMicroservices is a team organization technique, whereby disparate teams only communicate by well defined APIs. Any technology choices that come out of that are merely the result of Conway's Law. Any time you lean on code in a random GitHub repository, where you never speak to the author and just use the API you're given, you're doing microservices. This works well enough so long as the product does what you need of it. The problem is that when the product doesn't do what you need. If the microservices teams are under the same organization umbrella there is a strong inclination to start talking to other teams instead of building what's needed in house, which violates the only communicate by well defined APIs. This is where the ball of mud enters. If your organization is such that you can call up someone on another team, you don't need microservices. They're for places so big that it is impossible to keep track of who is who and your coworkers may as well be some random GitHub repository.
- JAlexoid 4y agoNo. That's not what microservices means. You're intentionally equating all services to microservices, which is not the case. This substitution is what is commonly known as a Strawman argument. You misrepresented an argument, to discredit it easier.
- randomdata 4y ago> That's not what microservices means. You're intentionally equating all services to microservices, which is not the case. Eventually everyone provides a service to someone, I guess, but there is a clear division between those who serve end users and those who serve the servers. The service that places your food down on the table at the restaurant is not thought of in the same was as those who get to the food to the restaurant. The latter camp is often known as a supplier, but we in tech call them a microservice instead. There is no suggestion that all services are microservices.
- JAlexoid 4y agoMicroservices is defined to be extreme decomposition, which is not the same as a service. And the biggest pitfall of microservice architecture, is the creep of loose coupling. Right now I work in an environment, where user account information is copied to every single microservice's internal DB... to minimize access time to that information... Restaurant provides you with a service - one single interface. Imagine if a restaurant used a microservice architecture? You'd be spending your time going from the fridge to the cooks, moving your food from one to another(because no cook will do the whole recipe), then going to the dish storage, having a separate cook arrange your food on your plate, etc.
- monero-xmr 4y agoMicroservices - let’s replace as many interfaces as possible with the slowest, flakiest, most complex mechanism - the network layer. Why call a function when you can wrap that function in an entire application and call it via API? Why have a single database when we can silo our data across 200 mini databases? Why have a single repo when we can have 200 tiny repos?
- agomez314 4y agoMicroservices solve many problems to those that understand the virtues and deficiencies of it - everyone else is just cargo-culting and committing themselves too much to something they don't understand (see Kubernetes).
- bradhe 4y ago> Microservices - let’s replace as many interfaces as possible with the slowest, flakiest, most complex mechanism - the network layer You do realise that most calls to block storage in AWS result in network traffic, right? The point is, abstraction is your friend.
- naasking 4y ago> The point is, abstraction is your friend. Yes, but the point they were making is that you don't have to abstract across a network boundary. A proper module system and package management can divide work and organization without introducing IPC overheads.
- Retric 4y agoLatency is additive. You get a small window within which people don’t notice and network calls quickly consume all of it. Micro services have a few advantages but unless you desperately need them it’s a huge hit to performance, productivity, and reliability unless it’s your only option. Netflix needed it because of their complicated network architecture with servers distributed inside various ISP’s, why do you?
- sidlls 4y agoOvercomplicated abstraction (e.g., DI frameworks) and unnecessary abstraction are not anyone's friends.
- amelius 4y agoLinux distributions are essentially a bunch of microservices running together (managed by e.g. systemd). It works well most of the time, of course until it doesn't. Not sure what a better approach would be, though.
- deleted 4y ago[deleted]
- philliphaydon 4y agoMost people create Nanoservices, not Microservices, if they did Microservices they would have a fraction of the number of services.
- baobabKoodaa 4y agoIs this a "No true scottsman" defense?
- layer8 4y agoI'd argue they should just do services.
- phyzome 4y agoWrong, milliservices are the way to go! Maybe centiservices, but no further!
- layer8 4y agoThere’s also the spectrum of decaservices, hectaservices, kiloservices, and so on to consider. It tops out at the infinityservice aka monolith.
- manojlds 4y agoThat's why we need 10x engineers.
- 708733454927516 4y ago(1x engineer looking for help from a 10x engineer) Q: Hey, do you have a microsecond? A: I did...
- layer8 4y agoYou’d need a 1000x engineer to turn a microservice into a milliservice.
- jameshart 4y agoDon’t you find it weird that everybody else is either over or underengineering, but you, you engineer things exactly the right amount? I bet when you’re driving, you also tend to notice that everyone else is either an idiot driving way too slow in the middle lane or a maniac speeding past you. Nobody else drives as well as you do. It must be exhausting for these people to live in a world surrounded by strawmen, while they alone have achieved perfection. Which they will detail how they do in a later blogpost.
- disintegore 4y agoIt does not appear that you have read the article
- jfoster 4y agoI would argue the inverse. If you reject both extremes, and are somewhere in the middle, you probably are much closer to something reasonable. (both in engineering and when driving)
- philosopher1234 4y agoDoing the average of everything is a great way to be pretty wrong. If you have to guess, guessing average seems fine, but if you know better, going with the herd can be foolish.
- jfoster 4y agoIf the herd is at one extreme or the other, the middle ground is the opposite of going with the herd. It could be unpopular because it's wrong, or it might be the insightful choice. Critical thinking will probably help figure out which it is.
- jameshart 4y agoI actually chose driving speed very deliberately. When you drive down a freeway, no matter what speed you are driving at, you will see far more cars traveling at a different speed than you than at the same speed. The cars going at the same speed as you never pass you and you never pass them. The only cars you notice are the ones who are driving differently. It is easy to convince yourself that you are taking the sensible middle course, no matter what speed you are driving at. Because you can always point to an extreme outlier and say ‘I’m not that guy’.
- revskill 4y agoI just use microservice whenever i can't embed many languages inside each other (WASI is a solution). No need to run a microservice just to make some function call.
- patates 4y agoI find SCS [0] as a very pragmatic and functional alternative to Microservices, which usually fits better to most organizations. [0]: https://scs-architecture.org/index.html https://scs-architecture.org/index.html
- boudin 4y agoI'm always sceptical on big claims for or against specific architectural and infrastructural choices. Micro-services makes sense in specific cases and doesn't in some other, the same as monolith is an absolute no-go in some cases but a really good fit for some others. The correct choice is always the simplest for what you need, the tricky bit is understanding what you actually need. The right choice might be a complex solution because your needs require some complexity. Going for micro-services just for the sake of it, without the need for it is a bad choice, but it doesn't mean that micro-services are bad.
- phyzome 4y agoIt turns out you can't make complexity go away by moving it around.
- qaq 4y agoThe idea that an org that has hard time maintaining a properly structured monolith, will solve it's problems by shifting to building a distributed system was always strange to me.
- PartiallyTyped 4y agoThe distributed system has benefits that the monolith doesn't, like scalability and resilience to failures though it opens doors to new kinds of failures.
- roflyear 4y agoAmazing way to put it actually. You summarized it in a great way.
- rcarmo 4y agoI don't see enough insightful content on this to keep it on the front page, but it seems to have touched a sore point.
- JAlexoid 4y agoEvery decade a new set of engineers grows up and we get the same all over again. Monolith vs services fight has been going on in every decade, that I've been a developer in.