[HN Gopher] Give me back my monolith (2019)
___________________________________________________________________
Give me back my monolith (2019)
Author : winslett
Score : 295 points
Date : 2022-05-10 14:47 UTC (8 hours ago)
(HTM) web link (www.craigkerstiens.com)
(TXT) w3m dump (www.craigkerstiens.com)
| itsmemattchung wrote:
| These days, I try to not to prematurely optimize by setting up
| micro services from day 1. I find starting with a monolith, with
| an eye towards micro services, works well for most projects and
| as patterns and abstractions emerge, slowly design and provision
| micro services.
| jeffwask wrote:
| In my experience, the project to break apart a monolith often
| happens without a clear definition of what problems we trying to
| solve by breaking apart the monolith. Which ends up creating a
| raft of new problems plus the old problems and a bunch of sticky
| left overs that are perpetually "going away soon".
|
| And since you have no clear definition of why and what outcomes
| you expect, you also get massive scope creep in the middle of all
| this. Then you run into all the things no one planned for because
| there was no plan like how do we serve business functions like BI
| from our 30 new micro-service databases.
| linkdd wrote:
| Come to Erlang/Elixir (and OTP), you get the best of both worlds:
| - a mono repository - a single codebase for a single system
| - your micro services are supervisors and gen servers (and a few
| other processes) in a supervision tree - you decide which
| erlang node run which apps - your monolith can scale easily
| thanks to libcluster and horde - ...
|
| Also, there is the midpoint between monolith and micro service,
| and this is called Service Oriented Architecture (SOA), you could
| have: - a DAL (Data Abstraction Layer) service
| - a Business Logic service (talking to the DAL) - an API
| (talking to the Business Logic service) - a Frontend
| (talking to the API)
|
| Your API (or gateway, or whatever you want to call it) can serve
| as glue for third-party services (like Stripe, or anything
| unrelated to your business).
|
| Microservices are a solution for an organizational problem, not a
| tech one. You need multiple teams to work on the same system
| without blocking each others. This is a solution for huge
| corporations, not your 2 pizzas team startup.
| d3nj4l wrote:
| This has always been a beautiful draw of the BEAM ecosystem for
| me, but during my exploration of the space I found that most
| people were deploying BEAM applications the same way as any
| other, say, Rails app, and I couldn't find a "getting started"
| of sorts to deploy desitributed BEAM apps the way you describe.
| I'd be interested in resources like that, if you have any.
| linkdd wrote:
| A few months ago I started a series of articles about Elixir,
| K8s and libcluser[0], but unfortunately I did not have time
| to continue it yet.
|
| If you're using K8s, what I would suggest is:
| - create multiple releases of your Mix project[1] with
| specific OTP applications in each - one Docker
| container per release - one K8s Deployment per release
| - one headless K8s Service selecting the pods for all your
| deployments - use libcluster for automated cluster
| formation
|
| Then, with node affinity/tolerations, you can control on
| which physical node you'll run it (if you want).
|
| If you're not using K8s, you can use an Ansible playbook to
| deploy each distinct release on the target host, and you can
| use libcluster with a static cluster configuration. This will
| work the same.
|
| [0] - https://medium.com/@david-delassus/elixir-and-
| kubernetes-a-l...
|
| [1] - https://elixir-lang.org/getting-started/mix-otp/config-
| and-r...
| handsaway wrote:
| I've worked at two companies using Elixir/Phoenix and both of
| them treated it exactly like a Rails app and there was no
| discernable BEAM-y ness about it other than how the library
| worked under the hood.
|
| I asked the more senior Elixir devs if we should do something
| to take advantage of the platform and was met with shrugs.
| brightball wrote:
| Ha! Came here to say this but you beat me to it.
|
| https://news.ycombinator.com/item?id=31328580
| sergiotapia wrote:
| Warning: Compilation times suck for Elixir/Erlang. I'm
| frustrated almost daily when I make changes to my code and have
| to wait for 66 .ex files to compile after changing one single
| line of code in a heex template.
| Kototama wrote:
| Why do the other files get recompiled? they should be
| recompiled only if there is change in them.
| sergiotapia wrote:
| I have no idea. That's what I'm seeing when working with my
| project.
|
| Literally add one character to one of my liveview modules:
| Rebuilding... Compiling 67 files (.ex)
| tomjakubowski wrote:
| It's worth your time to investigate this, it's fixable.
| Check out mix xref to investigate dependency chains
| between files in your mix project.
|
| In the project I work on, it turned out a module `use`d
| by almost every controller included a function (totally
| unused, btw) which, through a little bit of indirection,
| caused a circular compile-time dependency between all of
| them. So any change to any controller caused hundreds of
| files to rebuild.
| sergiotapia wrote:
| Never heard of xref. I'll take a look thanks!
| devoutsalsa wrote:
| Probably macros.
| pablodavila wrote:
| This was improved in a recent release. Did you try with the
| latest version?
| jacquesm wrote:
| Hehe. Technically cheating though, nothing in Erlang will ever
| be really a monolith. But it's a great solution for the space,
| it does require a bit of unlearning before you can be really
| productive with it.
| mrloba wrote:
| I've had great success with having a monolithic code base with
| multiple entry points. Each entry point is sort of a micro
| service (or just service), but it can access the same db as the
| other services (if it makes sense), use the same types, and
| crucially, it can easily be integration tested with the other
| entry points. With full debug support.
|
| Such a "monolith" need not be the only one in the company. One
| per high level module or team works well.
|
| I guess my point is, it doesn't have to be either giant monolith
| or tiny micro services in separate repos. There's everything in
| between as well.
| gmmeyer wrote:
| IMO you should never create a new service unless it serves an
| engineer reason instead of an organizational one. There's a lot
| of tools to help out monoliths, and a lot of ways to make it
| easier to shard the monolith as well.
|
| Some services need it, like a backend intake platform of some
| sort that needs to have radically different performance
| characteristics than a user facing frontend. But for most
| services it just does not make a lot of sense to do this.
| fulafel wrote:
| This is dated 2019-03-13 and it says "It feels like we're
| starting to pass the peak of the hype cycle of microservices" but
| wasn't the peak already earlier? Looking at HN posts -
| https://hn.algolia.com/?q=microservices - it looks like a lot of
| the high voted posts against microservices were 4-7 years ago.
|
| Highest scoring one (2018):
| https://news.ycombinator.com/item?id=17499137
| jghn wrote:
| From what I've seen over the years HN is on the leading edge of
| trends. If one really monitors the bleeding edge it doesn't
| feel that way. But people tend to forget the very very very
| long tail behind the curve.
|
| We went through a hiring surge a year or so ago and I was
| astounded how many candidates had never used any cloud, GitHub,
| containers, micro services, modern tooling or language
| versions, etc. These are all things I assumed everyone had been
| using for several years now. Or if not, they'd already tried it
| and decided to move elsewhere. It was eye opening.
|
| On their on premises monolith skills will come in handy with
| the bleeding edge companies in a few years.
| fulafel wrote:
| The HN hype thermometer I think is still a good signal, like
| here at detecting when fads are over the hill.
| kgeist wrote:
| It also depends on what kind of monolith we're talking about.
|
| We've found that "moduliths" (modular monoliths split into
| clearly defined bounded contexts with public APIs) work as well
| as microservices for scaling development: each team is
| responsible for their own module, there are very few conflicts,
| there's no spaghetti because we have architectural reviews
| whenever a module wishes to cross the "module barrier" and call
| into another module etc. (i.e. introducing a new dependency). You
| can spin up as many modulith instances as you wish as well.
|
| The problem is that our modulith is written in PHP using a very
| popular enterprisey framework. PHP is based on the paradigm of
| spinning up a new process per request (php-fpm can recycle them
| but still), so every request ends up reinitializing the whole
| framework every time: its entire dependency injection tree. Every
| new module increases response times linearly, it doesn't scale.
| Another issue is that the single DB (common for monoliths)
| becomes the bottleneck, as all modules/contexts go through it.
|
| Our PHP modulith is very costly in terms of runtime. A similar
| request into a microservice is usually 20-50 times faster because
| it's written in Go and manages its own DB. I think if our
| monolith was written in Go or Java from the very beginning we
| would have less impressive results after switching to
| microservices. Stuff rewritten from scratch is also usually
| faster than tons of old accumulated cruft.
|
| Deployment/compilation is much faster now, the old monolith also
| used to have a lot of JS/CSS processing, PHP linters during build
| etc. so a tiny change to a module would trigger full
| recompilation of all modules running for 30-40 minutes. Each
| microservice is a separate deployment however, so a change to it
| only takes 1-2 minutes to deploy/release.
|
| My point is that when people are talking about monoliths vs
| microservices they are often comparing dinosaurs written 10-15
| years ago (PHP, old frameworks with bad design decisions, tons of
| accumulated spaghetti) to modern, more lightweight
| languages/tooling (for example, Go, k8s etc)
|
| I think a "modern modulith" has its right to exist and is a
| viable competitor to microservices, provided they use more
| lightweight frameworks/tools, use paradigms such as modules and
| CQRS, and if somehow they allow smart, incremental deployments.
| dang wrote:
| Discussed at the time:
|
| _Give Me Back My Monolith_ -
| https://news.ycombinator.com/item?id=19382765 - March 2019 (411
| comments)
| nomoreusernames wrote:
| this is about scale. dont make things in a certain way because
| someone tells you to do it. collect metrics and use science to
| figure out what is best for you and your team today. engineers
| are building and using the things have to be reasonably happy
| with their tools or you get teenage behaviour.
| flatearth22 wrote:
| Wherecombinator wrote:
| As a junior engineer (only working 6 months), the K8s side of
| things has been my biggest barrier for learning. On top of having
| to learn about software engineering practices, I've had to learn
| helm files, deployments, services etc. It was/is very
| overwhelming. I know I'm new and naive but it seems needlessly
| complicated and it'll be another few rounds of abstraction beyond
| K8s before people are happy with it.
| nostrebored wrote:
| It's important to separate out microservices and kubernetes.
| They aren't the same thing, and Kubernetes isn't the only way
| to run microservices. Tons of companies were running
| microservices prior to kubernetes ever launching.
|
| The core idea is that services communicating via an API that
| have self-contained infrastructure is easier in a large
| organization, easier to scale, and allows you to make the right
| technical decisions for the problem.
| WerBn wrote:
| I relate so much with this article I've had a previous experience
| with a backend monolith repo, and these days I have to deal with
| a backend that has 20+ repos. It is hell. Duplicated code,
| duplicated logic, duplicated tests, duplicated settings, an hell
| to introduce newbies to the architecture, async calls to external
| basic APIs that could've been just simple method calls.
|
| I think that the one major disadvantage of having a big monorepo,
| is that with those multiple entry points, you might end up with a
| bunch of unused dependencies. But even that is manageable I
| think: you can have different package dependencies definitions
| whilst using the same codebase.
|
| I've always worked with small teams (max up to 5 or 6 developers)
| and that's another point in favor of monorepos. I understand that
| big companies might want to have different teams working on
| different repos, for organisation reasons.
| papito wrote:
| They don't have to be micro - they can just be services.
| alaricus wrote:
| Microservices are a great idea, if you don't religiously try to
| make everything a microservice.
|
| I feel more inefficiencies were caused by forcing a microservice
| solution to every problem; than by big monoliths.
| kabdib wrote:
| One wrinkle I liked was to build a monolith, distributing the
| same bits everywhere, and to configure the actual services to
| start on an instance-by-instance basis. This simplifies
| distribution (e.g., "unpack this single zip file, it's got
| everything") and you can rapidly change what is running and where
| with a command-and-control system of your choice.
|
| I can't imagine having different build products and deployment
| stories for every service type, nor can I imagine
| institutionalized version skew of more than a couple of weeks.
|
| This probably doesn't scale to large teams, but it let a small
| team work pretty effectively with thousands of microservices.
| john-tells-all wrote:
| You're advocating monolithic _packaging_ (simpler), with
| multiple _services_ (more flexible). Sounds great!
| brightball wrote:
| This is one of the big reasons I got into Elixir.
|
| The way that you're encouraged to architect your code makes it
| really easy to separate a specific piece(s) if you need to. The
| functional, no-side-effects approach combined with Elixir's
| ability to easily communicate between nodes means that if I need
| to separate a particular set of functionality to certain
| servers...it's just moving things around.
|
| If I take a function call_me(arg1, arg2) and it returns a result
| without side effects, it's no different for me to say
| call_me(node, arg1, arg2) because it's still going to give me the
| same result just from a different server.
|
| This flexibility means that I can comfortably built a monolith
| and not have to worry about having to untangle it later if I need
| to. I love it. It gives me long term peace of mind with short
| term productivity.
| Havoc wrote:
| Right tool for the job should have been the message all along.
| nixpulvis wrote:
| Conway's Law does not demand Microservices, it describes
| abstraction barriers. Forcing conflicts to be resolved in VCS as
| opposed to at runtime is a feature of monoliths, not a bug.
| benreesman wrote:
| The pros have an RPC when a program that needs to timing on one
| SKU needs something from a program that needs a different SKU.
| Otherwise, you don't do the RPC.
|
| Micro service or monolith? Hmm, I'd like F1 car or tank. If it
| fucking matters, you know which one you need.
| revskill wrote:
| This is bullshit article, sorry for bad words, but it's hard for
| me to keep using monothlich for any reason. Monothlich is the way
| to hell. It kills developer's productivity and team velocity by
| margin cost.
| fmakunbound wrote:
| At a company I work at currently, they have microservices, but
| they moved the monolith into the side-car. Best of both worlds.
| est wrote:
| My theory: if you can easily swap local-procedure-calls with
| remote-procedure-calls, then it's a well-designed system,
| monolith or not.
| Milner08 wrote:
| This is something I would agree with. If you can keep the
| boundaries in place but work in the same process space you've
| managed to avoid the mess often associated with Monoliths and
| the overhead associated with Micro services.
| deckard1 wrote:
| the dream of transparently/automagically swapping local calls
| for RPC is decades long now
|
| but you can't. Once you go RPC you hit the CAP theorem and need
| to deal with the reality of running a distributed system.
| Erlang is the only mainstream-ish production ready language I
| know of that attempts to solve this. And it is still very much
| caveat emptor. This is also where you might also bring up
| nondeterministic latency characteristics.
| fennecfoxen wrote:
| Okay, Craig, you can have your monolith back when you can get
| your engineers to care _in the slightest_ about keeping the
| codebase organized instead of turning it into a big ball of mud.
| I 'm talking encapsulation. I'm talking well-defined interfaces
| that aren't glued to specific implementations. I'm talking some
| sort of dependency inversion, dependency injection, service
| locator patterns, any of that. I'm talking real use of the
| single-responsibility principle, all that software-engineery
| stuff that everyone _ignores_. Because I understand what you 're
| getting at 110%, but by and large, all this stuff doesn't happen
| otherwise.
|
| Until then you're going to have these things forced on you by
| your local Architect, forced on you by running a bunch of
| separate processes on separate containers with DNS as the
| cluster's service-lookup framework.
| dagss wrote:
| How about, you can have microservices back when the
| engineers/architects care _in the slightest_ about defining
| domains between services and having a direction or overall idea
| for how they communicate.
|
| It's easy to get to a point where you have a big ball of mud of
| 100 micro-services where each new features touches 20 of them,
| and just hack in whatever new APIs everywhere that's needed to
| push a new feature out (but probably buggy due to async state
| and race conditions that noone was trained enough to figure out
| up front).
|
| All that is pretty equivalent to what you talk about with
| monoliths.
| Trasmatta wrote:
| I'd rather have one codebase that's a big ball of mud than 10
| mini balls of mud that combine to make one immensely
| complicated ball of mud. At least a stack of messy method calls
| is much easier to debug than some data that travels through 5
| different systems before it gets to the user.
| ascendantlogic wrote:
| I wonder if anyone who wants to bring back the monolith has ever
| worked on a true large monolithic codebase? Not something that's
| like 5-10k lines of code excluding frameworks, but monsters that
| are 100k+. Where test suites take an hour to run end-to-end and
| you've got 50+ devs all issuing pull requests in the same
| codebase? I feel like webapps usually have a sweet spot in terms
| of size and logical reach. This whiplash hype cycle of "X" and
| "anti-X" just exposes the ever lingering problem of letting blog
| posts on HN determine your architecture decisions.
| seti0Cha wrote:
| Sure. Used to be, that's how it was done. Some things sucked
| about it, others were easier. For example, not much in the way
| of versioning problems. On the other hand, if somebody broke
| the release, nobody's new feature made it live. You also had to
| allow for extra testing time...continuous deployment D is not a
| great strategy in this environment. We had a week of
| integration testing for release candidates, unit tests, smoke
| tests, data integrity tests, UI tests, performance tests, etc.
| We also had a QA team that signed off on releases. It was
| actually pretty rare that you collided with other developers
| because teams were focused on their own areas of the codebase.
| breakalot wrote:
| Usually codebases are organized into modules/classes/etc and
| most test suites can run specific test cases (or groups of
| tests, specific domains, etc).
|
| I think if you can't do that in a codebase, then one has bigger
| organizational problems than the technology itself.
|
| Also assigning many developers to work on the same set of files
| is a recipe for disaster (if said developers cannot get along
| or organize themselves) while working on the very same
| place/file.
| folkhack wrote:
| I have as well, and honestly I'd classify something that's
| 100k+ LOC as a "mega-monolith" vs. what devs would
| traditionally consider a "monolith"
|
| You don't get to that LOC count without _huge_ teams and
| decades of time. Any project of that timeline /complexity/size
| should constantly be having functionality split off so that
| organizational units can be better groked/understood. To put it
| a different way, when projects hit this sorta size I have
| experienced them naturally shedding off functionality that
| makes sense to be external in a service-based development
| strategy.
|
| These are the situations where it 100% makes sense for
| microservice architecture as you've hit the social/technical
| complexities where breaking things into organizational units
| makes sense.
| CipherThrowaway wrote:
| I feel like I am going absolutely nuts reading this thread.
| 10K LoC is 2-3 months of work for a single person hobby
| project. 100K LoC is maybe a 2-3 person dev team for 2 years.
| That's assuming a refactored codebase with no copy-paste
| repetition. "Append only" codebases with heavy copy-pasting
| can easily get larger than that in shorter amounts of time.
|
| Huge teams and decades of time gets you to 1M+ range, not the
| 100K+ range.
| folkhack wrote:
| In a large corporation with tons of people constantly
| reinventing the wheel for no reason only for resume bullet
| points... where you spend two months on test specs before
| putting down a single LOC because "TDD", where you have to
| work with regulators, auditors, etc...
|
| I feel weird defending myself but... yeah. This is actually
| my experience.
|
| I get that teams at FAANGs/startups can typically move
| faster but for your run-of-the-mill corporate America
| development teams people do not move that fast.
|
| Personally, I have only moved that fast at startups which
| is why I typically find myself at them.
|
| Again, this is anecdotal to my personal experience.
| CipherThrowaway wrote:
| That makes sense. It just shows how much variation there
| is across different areas.
| pixl97 wrote:
| I only wish the monoliths my customers were dealing with were
| tiny 100k LOC projects. I've seen 5MLOC+ nightmares filled
| with all the terrors you'd expect like unused libraries and
| dead code that looks should be unreachable, but actually is
| and creates security issues.
| jandrewrogers wrote:
| Wait, what? 100k+ LoC is more like a "two-pizza" team and a
| few years, empirically. And this is in C++, a language where
| LoC don't flow nearly as quickly as in other languages. Even
| extremely complex code bases (think database engines) are
| entirely manageable at this scale and beyond without
| introducing microservices. Monoliths will scale into millions
| of LoC with little loss of effectiveness if your code base
| and processes are setup correctly.
|
| You are describing the consequences of poor architecture and
| process, not anything intrinsic to software projects.
| folkhack wrote:
| > empirically
|
| Right, and our empirical observations over these topics are
| different.
|
| I just read your profile and frankly the
| projects/industries that we are involved in are _very_
| different, only confirmed by throwing "C++" out there -
| the closest I get to that is some hobbyist C development.
|
| I apologize for agreeing with parent comment's
| generalization at 100k LOC being a "mega-monolith", along
| with what I added with team sizes/decades for timelines.
| Empirically and anecdotally this is what I _personally_
| have observed, specifically in regulated fields ie:
| banking, payments, and education. This is a perfect example
| as-to what happens when I don 't include the word
| "anecdotal" in my HN comments...
|
| Developers from different industry niches have very
| different ideals in regards to what a "monolith" is, or
| what a "two-pizza" team is capable of over time. I find
| your "wait what?" comment to be a bit dismissive, only to
| end your comment directly telling me what I am describing
| which clearly implies I don't know what I'm talking about.
|
| We likely just have different experiences with project
| complexities, sizes, teams, etc. Sorry if this comes off as
| aggressive.
| papito wrote:
| Ten years ago I worked on a monster that was half a gig on
| checkout. Assets, everything. It was an e-commerce site. And it
| was beautiful. Single set of dependencies, easily tested, one
| CI/CD pipeline.
|
| It was an egregious Spring/Struts1 app, and it was a breeze to
| develop on. Fixed my first bug on day 2 of the job. With
| microservices, would have taken me 3 months.
| dboreham wrote:
| 2G here.
| CipherThrowaway wrote:
| At my first job I inherited a 250K LoC monolith which I had to
| continue to develop and also operate. It wasn't great but I got
| by. I don't think I could have managed if that 250K LoC had
| been strewn across a dozen microservices with all the
| accompanying complexity and extra degrees of freedom in
| deployment and operation.
|
| SoA is superior when you have large numbers of devs
| coordinating and working on the same product. For smaller teams
| monoliths seem to be the way to go.
| muskmusk wrote:
| > I wonder if anyone who wants to bring back the monolith has
| ever worked on a true large monolithic codebase?
|
| Probably not, that's really the point :)
|
| Although I think the limit is significantly higher today.
| Monorepo tooling is orders of magnitude better than 10 years
| ago.
| tompazourek wrote:
| Can you recommend something good in that area of monorepo
| tooling?
|
| I read about Bazel, which looked really nice. Any other
| interesting tools to check out?
| drbojingle wrote:
| At a certain scale monoliths will no doubt break down but I
| believe the author and many other developers are bothered when
| monoliths are an optimal solution for their scale and problem
| space but end up replaced by one that's suboptimal.
| [deleted]
| zo1 wrote:
| I have. LoC was in the millions. Half a dozen languages too for
| the different parts of thw monolith. Worked on by a team that
| peaked at 100 or so. Multi hour build times too. SVN too!
|
| Monolith is still better in my view, despite having experienced
| that.
|
| The key IMO is to have a clear and singular vision and how all
| the different parts need to fit into it. If you let each little
| clump of people do their own thing, then you will have chaos.
| jandrewrogers wrote:
| I've worked on large monoliths (100k LoC is not "large") and
| have a strong preference for them because I've also worked on
| large microservice architectures. A monolith with a strong
| architecture and development process works well. Microservice
| architectures are often a fig leaf for poor architecture and
| development process, while introducing new problems and
| increasing development effort. It is always less expensive in
| the long run to fix the architecture and process problems than
| to sweep them under the rug with microservices.
|
| I understand that microservices often become necessary in
| organizations when they are constitutionally incapable of
| addressing the root issues directly. But we shouldn't normalize
| introducing microservices so that we can ignore poor
| architecture and process, which underlies the majority of cases
| I see.
| cosmiccatnap wrote:
| No
|
| As someone who has spent the last 3 years of their life
| maintaining and scaling one this is madness.
| light_hue_1 wrote:
| If you use the wrong tools, everything looks like a disaster.
|
| Microservices on AWS with lambda+dynamo+auroa+api-gateway work
| very well. There's built in transparency. There is logging. You
| can set everything up with terraform.
|
| Terraform makes the setup trivial. Compared to monoliths that
| I've seen that involve a lot of brittle manual steps, it's not
| even a competition. AWS Lambda with xray and other logging tools
| makes tracking down errors trivial. I have yet to see a monolith
| with anything comparable.
|
| "Oh but I get a stack trace in my monolith" is false
| advertisement. How useful is that stack trace when the stack is
| corrupted? Or when memory is corrupted because one line in
| another part of the monolith has an error that slowly screwed up
| some datastructure in another part of the monolith? I'll take
| Lambdas that are all short, totally isolated, and easy to
| understand, any day. Debugging and understanding is much harder
| with a monolith.
|
| And yes. To test, you need to bring up the entire working
| application. Just like you need to bring up the monolith. Oh? You
| mean, most people who test monolith don't bring them up, they
| just test some mocked version of some module in isolation? Well,
| they're probably testing the testing framework itself more than
| the monolith. With localstack you can bring up the entire AWS
| setup locally, automatically, run component and end to end tests.
| It's far more testable than a monolith. And far more obvious when
| an interaction is not tested.
|
| Monoliths are dead. Stop writing them. And start learning modern
| tooling.
| dagss wrote:
| The way you use functions on Amazon sounds like it could be a
| monolithic development style to me. Independent functions is
| still a monolith if they use the same database (IMO). It's
| micro-services if you start to use different databases and have
| async state between them, which is orthogonal to what you bring
| up here.
|
| What you bring up here is a discussion of execution
| environments for your code -- similar to a discussion of the
| best OS or programming language -- not whether the code is
| monolith or micro-service.
|
| 50 Amazon Lambda functions that all use the same database /
| data stores and understands the same data directly without
| going through APIs is definitely a monolith in my book.
|
| PS: If you first allow for the possibility of a completely odd
| event like a corrupted stack trace (what are you programming
| in, pure C?) then to be fair I think you have to allow for the
| possibility of a bug in Lambda leaking state across invocations
| too.
| glouwbug wrote:
| If anything, it's great for the resume
| shroompasta wrote:
| If you're dealing with any complex architecture, there will be
| portions of your service that will be hit more than others.
|
| I'm currently building a backend in which will need real time
| capabilities and also standard restful http services.
|
| Separating the real time service which will need a significant
| amount of performance more than the restful services will help me
| better scale.
|
| Furthermore, the entire backend is written in python, because
| that is what I'm currently capable of at the moment, but in the
| future, migrating the real time service to Go will be heavily
| favorable - by separating it into its own service allows for that
| rewrite to happen at ease.
|
| Now, there are many cases where building microservices are an
| overkill, but this isn't a one size fits all approach as the
| author would suggest, and I think we should all be tired of
| hearing a this or that type of article.
| dfee wrote:
| On the NodeJS / React ecosystem - no one really wants you to do
| monoliths.
|
| NextJS, for example, doesn't let you manage service lifecycle
| methods (unless you write a custom server - which they explicitly
| warn you against). NextJS wants to be special, that's dumb and it
| sucks (well, in the context of using it to drive your SaaS
| platform, it's pretty smart).
|
| Remix, for example, wants to control your client/server API
| calls, so you're hard pressed to use other tools like GraphQL,
| and incur the risk for growing into microservices if you need it.
| Same story as NextJS about being special and probably driving
| SaaS platform sales.
|
| Amazon just makes you manage an alphabet soup worth of products,
| which are all pretty expensive - unless you want to just lambda
| it... meaning custom runtimes and ... back to microservices.
|
| Point: microservices aren't just driven by your org anymore,
| they're pushed by vendors.
| kall wrote:
| Isn't an average next app pretty much a monolith? It gets split
| into lambdas when you deploy it, but the development experience
| feels monolithic to me.
|
| If I want to use some function, I often just import it and call
| it directly, instead of calling one serverless function from
| another over http. That means the function gets bundled into a
| few lambdas, but so far, I've had no issues with that. The
| monolith abstraction hasn't really leaked for me.
| dfee wrote:
| I'm all for a monorepo - or to a lesser degree, utility
| functions that are re-usable across components. That's not
| what I'm talking about.
|
| Running NextJS as a handful of lambdas is fine, but you still
| likely need to initialize other services in the background
| (like databases _)... otherwise you have a monolithic front-
| end... as in: "my monolithic front end talks to my monolithic
| back end, so I really have two micro/macro services", and
| maybe I should investigate breaking the FE/BE down into
| smaller components".
|
| _ sure, you can use pgbouncer, etc. but it becomes sorta cost
| prohibitive to run a few apps.
| kall wrote:
| Monolith + a database, that's always implied, isn't it?
|
| How you make the database connection work with serverless
| connection requirements seems like a minor issue. I haven't
| used it but it seems like next + prisma (+ tailwind lol) is
| the default stack of tutorial writers these days.
| dfee wrote:
| "How you make the database connection work with
| serverless connection requirements seems like a minor
| issue."
|
| It's really not. See... databases like PostgreSQL aren't
| designed for an infinite number of simultaneous
| connections (doing things like, checking for a logged in
| user, and auth). This is where something like pgbouncer
| comes in - _that_ at least takes care of transaction
| boundaries - because we 're a monolith, remember?
|
| Now you're also setting up the state of your application
| as global variables. Seems like a pretty poor choice, and
| now you also need to figure out the gotchas with HMR
| here.
|
| Let's not even get into the fact that a lot of code isn't
| meant to be (or cannot be) bundled by webpack. So now
| you're resorting to a custom Webpack config to exclude
| certain modules. [0]
|
| On AWS, pgbouncer is called "RDS Proxy" and runs you
| $11.16/mo. [1]
|
| That's not even getting into the cognitive overhead of
| just "rolling out an app over a weekend" now being a
| weekend adventure in and of itself - again managing an
| alphabet soup of services either all within AWS or
| between AWS and Vercel.
|
| [0] https://nextjs.org/docs/api-
| reference/next.config.js/custom-...
|
| [1] https://aws.amazon.com/rds/proxy/pricing/?nc=sn&loc=3
| leerob wrote:
| Hey, Lee from Vercel. I lead the Next.js community. We do
| encourage folks to use monoliths, if they'd like! That's
| partially why we believe in Turborepo so much (happy to share
| more on that if you'd like).
|
| Are there specific lifecycle methods you want to tap into with
| Next.js? Open to feedback there. The reason the "custom server"
| is not recommended (it's poorly named, I'd argue it's an
| "ejected server") is because the main use cases folks were
| ejecting for have since been merged into Next.js core (like
| internationalization).
| dfee wrote:
| Hey Lee - imagine that I've got a database I need to
| initialize on startup / teardown on shutdown. Where can I do
| this? It's inherently an async concept. There are no hooks.
|
| The docs for Custom Servers [0] begin with a bunch of
| language and warnings strongly encouraging you to forego this
| route. The consequence? I don't know - it feels like it's not
| maintained, and maybe won't be there between major versions.
|
| [0] https://nextjs.org/docs/advanced-features/custom-server
| mwcampbell wrote:
| Remix seems to be a counter-example. The jokes app tutorial [1]
| is as monolithic as they come.
|
| [1]: https://remix.run/docs/en/v1/tutorials/jokes
| dfee wrote:
| Monolithic - yes. However, my concerns with Remix are that it
| intentionally doesn't align well with the premise of GraphQL
| - for better or worse. However, that's a very common pattern
| when you _do_ need microservices.
|
| I.e. Remix doesn't have a good story for off-boarding from a
| monolith - so it's inherently risky to build on top of.
|
| GraphQL really isn't that hard, and if I'm going to build an
| API anyway, why not just start with a piece that's going to
| eliminate the endless refactoring of data-stitching when the
| needs of my pages (or underlying components) change?
| deckard1 wrote:
| NextJS is an elaborate advertisement for Vercel's "serverless"
| cloud. I really can't feel sorry for anyone at this point that
| gets suckered into their sham. As a framework, it's also going
| to force you into a specific pattern.
|
| Skip Next and go straight for Express. NextJS does nothing
| useful that you can't easily do yourself, and only makes life
| difficult down the road.
|
| > they're pushed by vendors
|
| yes, Apollo with GraphQL, Vercel, etc. It's a huge cottage
| industry. But this is how IT has always worked. Just look at
| some of the garbage Oracle and IBM have been pushing since the
| '80s. If your org is falling for a slick sales pitch or the
| latest Google cargo cult, then that's on them. If you're in IT,
| then it's your responsibility to educate the execs on what they
| actually need. If they would rather listen to the sales guy
| over at Oracle than you (often likely), then it's time to move
| on.
| leerob wrote:
| Hey, Lee from Vercel - I lead the Next.js community and am
| focused on making sure Next.js works great self-hosted (e.g.
| Node.js server, Docker app, etc) with support for all
| features. I've written docs[1] about it as well as made
| videos[2]. Open to any feedback you have on how we could make
| this more clear!
|
| [1]: https://nextjs.org/docs/deployment#self-hosting
|
| [2]: https://www.youtube.com/watch?v=Pd2tVxhFnO4
| phillipcarter wrote:
| Yes, corporate-funded OSS has a way to make things work well
| on their paid product.
|
| But Next.js is also just a well-built framework that won some
| hearts and minds because it's ...a good framework, not
| because of some extremely slick salespeople.
|
| And if being a technical contrarian is interesting, you can
| always use it with one of Vercel's biggest competitors:
| https://www.netlify.com/with/nextjs/
| tonymet wrote:
| The lack of a stacktrace alone should be a hard blocker to
| microservice migration.
|
| After that, the amount of cpu (i.e. dollars) and wall time wasted
| on encode-decode.
|
| Anyone who does a microservice migration is not accounting for
| the above two costs.
| Milner08 wrote:
| Or maybe they are, and they still think its worth it? Stack
| traces are not an issue I've faced, good tracing helps a lot
| here. Encode-decode is a minor issue in comparison to the
| issues they are often trying to solve (which may not always be
| technical, especially at larger orgs)
| unnouinceput wrote:
| Both styles have their places. I've done migrations of monolith
| to microservices and I've done microservices to monolith. In the
| end is about what's best for the project/client, not the purism
| of "I only do xxx or only yyy". If you're one of those developers
| then don't call yourself "senior", you're still in the mindset of
| a junior.
| roflyear wrote:
| Agreed 100%. Another pain point that prevents developers, who
| love to think they are rational people (lol) to even start to
| have a productive conversation about microservices.
| staticassertion wrote:
| > Setup went from intro chem to quantum mechanics
|
| Doesn't really seem fair. On the one hand you might need to do a
| bit of work so that you can say `docker-compose up` or `nomad up`
| or whatever, but at the same time there are plenty of issues with
| running binaries/databases directly on a laptop - version skew,
| for instance.
|
| > So long for understanding our systems
|
| This is fundamental to all asynchronous systems. You don't have
| backtraces anymore. If your service has concurrency primitives
| you probably already have to solve this problem with tracing,
| microservices just give you another asynchronous primitive.
|
| > If we can't debug them, maybe we can test them
|
| Bringing up your entire application is what you'd have to do in a
| monolith as well, I don't understand this criticism. Also,
| "teaching" your CI to do this is 0 additional work - it's gonna
| be another "docker-compose up" or whatever, generally speaking.
|
| Our microservice codebase runs on laptops just as it runs in the
| cloud. It's pretty nice.
|
| With regards to "That is probably a bit too much effort so we're
| just going to test each piece in isolation" - again, this is the
| same thing with your monolith. You'll just do this at the module
| level.
|
| This is really a "right tool for the job" situation. And that's
| hard for people to understand, since oftentimes you don't know
| what you're building upfront.
| lxe wrote:
| Hey, the longer it takes to understand, iterate, and work on a
| particular architecture, the more money you're making per task
| completed as an engineer... so the more ridiculous the
| architecture with which you're working, the slower your work is,
| the longer it takes to get done, the longer you stay employed!
| ChicagoDave wrote:
| If you have a simple crud system, a monolith I'd likely
| preferable. If your business domain has a lot of complexity,
| which you can discover through Event Storming, then breaking up
| the monolith will provide clear development criteria and much
| simpler maintenance.
| roflyear wrote:
| I think the biggest pain point for me is the almost constantly-
| changing definition of "microservices" - at work, whenever
| someone says "microservices" they really mean a services
| architecture. I can largely get behind that. Because when you say
| services architecture, to me anyway, that doesn't mean everything
| has to be a "service". Some stuff can be on the same machine if
| you do not have a firm point of separation between the services.
| Maybe they will share some code eventually... ok... put them
| together, who cares?
|
| Last time I asked our ops guy to define microservices for me, he
| couldn't - instead he told me to read a 400 page book by some
| popular microservices preacher (who of course makes a lot of
| money by consulting for companies looking to use or currently
| using microservices ;))
|
| If you cannot explain the general concepts to me, maybe you do
| not know what it is, and I think that is a big part of the
| problem.
| staticassertion wrote:
| It's SOA with specific patterns and disciplines, centered
| primarily around the concept of the 'bounded context'. But if
| you want to just start with SOA and learn those patterns as you
| go, or dig into the book/ blog posts on bounded contexts, go
| for it.
| bcrosby95 wrote:
| The first time the phrase was coined, it meant SOA using REST
| instead of SOAP.
|
| Today I don't know wtf it means. I guess it depends upon who
| you ask.
| eweise wrote:
| "Micro" is a very unfortunate part of the name.
| jayd16 wrote:
| Yeah, I think the most palatable definition of microservices is
| just SOA with no arbitrary lower bound on how much code a
| service needs to justify itself.
| jameshart wrote:
| SOA usually involves a bunch of separate services, but all
| connecting back to the same shared RDBMS. That's the biggest
| shift in microservices - no shared data stores.
| roflyear wrote:
| Yeah with some extra best practices thrown in - most of which
| I strongly agree with!
| Ensorceled wrote:
| I remember a talk a few years ago where the CTO of a local
| startup was gushing about microservices and how productive they
| made his team. Sounded like an tech evangelist who had drank
| their own koolaid.
|
| Then one of the "questions" in the Q&A was a pretty aggressive
| attack based on how unproductive the skeptics company had been to
| date and how they were on the verge of failing.
|
| The speaker asked how many development teams they had and what
| was the size of their DevOps/Tooling team(s). When the skeptic
| admitted they only had a few developers, the speaker recommended
| they IMMEDIATELY pivot to Django/Rails/Node.js/.Net; "whatever
| you are most comfortable with". And then said "Why are you still
| standing there? You need to pivot tomorrow morning."
|
| I think of those two questions every time I read or consider
| microservices. "How many teams. How big is your DevOps/Tooling
| team."
| fictionfuture wrote:
| To be fair, most micro service setups and tutorials have been
| overly complicated; however, let's agree that distributed
| workloads and architecture are superior in a number of ways.
|
| Generally, when people discuss going back to the "monolith" they
| just haven't found the right distributed architecture.
| roflyear wrote:
| Big one for me is logging, auditing, etc.. is always an
| afterthought. I am guilty of this as well, but really it should
| be the first thing you do, and do very well, in a way that is
| really convenient for everyone, before you think about anything
| distributed.
| [deleted]
| duxup wrote:
| I want to know how many people who are using "microservices" are
| actually using "microservices" with separate databases for each
| service, separate teams and so on...?
|
| If you asked my boss, we're using microservices. But really we're
| just taking common tasks and breaking them out to their own
| service. Now that's kinda like microservices, and it is very
| handy ... but it is not the full definition that I know of.
| pantulis wrote:
| A decoupled SPA+BFFE is usually, incorrectly called a
| "microservices architecture".
| atx42 wrote:
| Why do we organize by shape, and not by function in our
| monoliths? We put all our controllers in a package, all our DB
| accessors in another package, all our "data objects" in another
| package. Even in OO languages like Java where we have package
| accessors that never get used because we layout our code such
| that package scope can never be used. We instead layout the code
| according to "shape".
|
| When figuring out what to spin-off as a microservice, we do this
| by functionality. Why not just make it easier in the monolith and
| organize by functionality instead? Let's act like 4yr olds, not
| 3yr olds: https://pubmed.ncbi.nlm.nih.gov/12090481/
| metaltyphoon wrote:
| The wording you are looking for is called "Vertical Slicing".
| After using it, I'll never go back to "shapes" anymore.
| atx42 wrote:
| Thanks, I didn't know there was a name for it. But every
| single code example out there is an anti-pattern to this as
| far as I've seen.
| PaulKeeble wrote:
| Microservices was always a solution to the organisational problem
| of getting more developers working on a system at once. A lot of
| people working on one code base over the top of each other often
| causes problems and issues with ownership. The solution was
| services independently developed with the trade off cost being
| increased complexity on a range of things.
|
| There is an essay in the mythical man month about Conways law and
| microservices are very much about a way to use Conways law to
| achieve scale of development. You likely don't need microservice
| until you hit a scale where the monolith is a real pain point.
| You can probably cope with a monolith especially with some
| reasonable design effort up to the 100 developers maybe more with
| a lot of separation but at some point in the >25 developers range
| it becomes cheaper and easier to switch to multiple deployed
| units of software and deal with the increased system complexity
| and interface designs and the inherent versioning issues it
| causes.
|
| It is easier to start with a monolith, find the right design and
| then split on the boundaries than it is to make the correct
| microservices to begin with.
| staticassertion wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once.
|
| I don't really agree. It's probably the most agreed upon
| benefit, but there are others. Fundamentally, microservices
| allow you to isolate state. I can take two services and split
| them up - and now I've split their state spaces. I can put a
| queue service between them and now I've sliced out the state of
| their communication.
|
| This slicing up of state has a ton of benefits if done right.
|
| 1. Isolation of state is basically the key to having scalable
| concurrency. Watch the Whatsapp talk on Erlang and they say
| "Isolation, Isolation, Isolation".
|
| 2. Isolation of services is great for security. You can split
| up permissions across your services, limit their access in a
| more granular way, etc.
|
| Those are pretty nice wins. They're achievable through
| discipline in a monolith (heavy use of module boundaries, heavy
| use of immutability - something most mainstream languages don't
| encourage) but a network boundary really forces these things
| and makes unintentional stateful coupling a lot more painful.
|
| > It is easier to start with a monolith, find the right design
| and then split on the boundaries than it is to make the correct
| microservices to begin with.
|
| I disagree. Starting with a bad set of microservices can be
| fixed by merging. Merging two codebases is trivial compared to
| splitting. Again, if I have isolation between the services,
| even if the slicing up was done badly, even if they're coupled,
| I can just remove the layer between them.
|
| Splitting has to start from a place of coupling and then try to
| decouple - this is especially hard with languages that
| encourage encapsulated mutable state (most of them).
| ori_b wrote:
| You've moved the state around, but the state is still there
| -- just hidden. It's hidden in the network communication
| instead of the function calls.
|
| And the distributed, cross-service mutated state is a hell of
| a lot harder to trace and debug.
| staticassertion wrote:
| I didn't say it removes state. I said it split the state up
| and isolated it. That's critically important - you
| physically can not mutate state across a network, you have
| to pass messages from one system to the other over a
| boundary, either via some protocol like TCP or via
| intermediary systems like message brokers.
|
| Joe Armstrong talks about this better than I'm going to:
| https://youtu.be/lKXe3HUG2l4?t=1438
|
| That timestamp is rough, I just found a related section of
| the talk.
|
| > And the network-defined state is a hell of a lot harder
| to trace and debug.
|
| There's no such thing as network-defined state. I assume
| you're saying that it's harder to debug bugs that span
| systems, which is true, but not interesting since that's
| fundamental to concurrent systems and not to microservices.
| xorcist wrote:
| I think you have a very narrow idea about what "mutating
| state" really means. You seem to talk about DMA access
| only. But you can manipulate the state of an application
| by writing to a shared data store, by calling an API, and
| countless other ways. It is really more of a concept for
| us humans to define where an application begins and ends.
|
| Let's take an example. If we have two services that wants
| to keep the full name of a logged in user for some
| reason, that piece of state can be said to be shared
| between the applications. Should one service want to
| change that piece of data (perhaps we had it wrong and
| the user wanted to set it right), the service must now
| mutate the shared state. It does not matter whether it is
| done by evicting a shared cache or if we write the
| updated data to the service directly, we still speak of a
| shared state that is updated.
|
| Now we can stipulate that the more of these things we
| have, the more coupled two pieces of software is, which
| generally makes reasoning about the system harder. It is
| not as black and white as one type of coupling is
| considered acceptable and the other isn't, but some types
| are easier to reason about than others. Joe really
| thought hard about these things and it really shows in
| the software he wrote.
| staticassertion wrote:
| We all share state in that we all exist within the same
| universe. But the universe has laws of causality, and Joe
| advocated that software should always maintain causal
| consistency.
|
| A database is not needed for your example. You could
| replace it with an actor holding onto its own memory. But
| all mutations to that actor, which the other actors hold
| references to via their mailbox, are _causally
| consistent_ and observable.
|
| That is the premise of the talk I linked elsewhere.
| infamia wrote:
| > I disagree. Starting with a bad set of microservices can be
| fixed by merging. Merging two codebases is trivial compared
| to splitting. Again, if I have isolation between the
| services, even if the slicing up was done badly, even if
| they're coupled, I can just remove the layer between them.
|
| There is still coupling in microservices, it has just shifted
| to messaging, networking, and queuing. If you get any of
| those parts wrong, you have a worse mess to untangle with
| less mature debugging/logging tooling than a monolith enjoys,
| all the while likely dealing with eventual consistency
| (depending on the design). I'm not saying don't start with a
| microservice, but it likely wouldn't be the very first tool I
| would reach for when starting out if a monolith would do the
| job effectively. Most things will never be hyperscale and
| won't benefit from the increased concurrency. You can go a
| very long way with a "majestic monolith" and a bit of care.
| atx42 wrote:
| I disagree. If you are able to merge them you spent the
| work to originally have them split. So more work to start
| with microservices. It goes back to agile, the easy
| solution is have a monolith and figure out later how it can
| be well-split.
| staticassertion wrote:
| > There is still coupling in microservices, it has just
| shifted to messaging, networking, and queuing.
|
| Sure, in the sense that your service is "coupled" to a
| queue and if you don't abstract that away it's hard to
| change that queue implementation. But in the sense of two
| services you wrote being coupled, they aren't, in terms of
| shared state. That gets pulled out. There is no way for one
| service to mutate the memory of another - it has to send a
| message to it.
|
| That can be TCP or it can be over some queue or stream or
| whatever.
|
| > If you get any of those parts wrong, you have a worse
| mess to untangle with less mature debugging/logging tooling
| than a monolith enjoys
|
| This is the case with any concurrent system. The fact that
| so many languages lack concurrency primitives is probably
| why people don't run into this more often. If you use
| concurrency primitives in your language, you already have
| this.
|
| > all the while likely dealing with eventual consistency
| (depending on the design)
|
| There's nothing eventually consistent about this system. It
| fundamentally has causal consistency (since messages from a
| service must come after messages to that service that
| triggered them), and it's perfectly capable of leveraging
| transactions.
|
| > I'm not saying don't start with a microservice, but it
| likely wouldn't be the very first tool I would reach for
| when starting out if a monolith would do the job
| effectively.
|
| To each their own. I much prefer it. It's far simpler to
| maintain "good" design since the network boundary creates a
| hard line in the sand that you physically can not violate.
| blowski wrote:
| > That gets pulled out. There is no way for one service
| to mutate the memory of another - it has to send a
| message to it.
|
| If it's well-designed, and that's a big if. Most
| implementations I've worked with constantly mutate each
| others's state.
| staticassertion wrote:
| No, it's physically impossible. You have causal
| consistency across services, not within services.
|
| https://youtu.be/lKXe3HUG2l4?t=1438
| blowski wrote:
| Codebase A writes data to datastore. Codebase B mutates
| it. Codebase A loads it back in, assuming it's still the
| same.
|
| Boom. You've mutated codebase A's memory.
| staticassertion wrote:
| I would hope it's obvious that you _haven 't_ mutated A's
| memory, but I'll just suggest you watch the talk.
| blowski wrote:
| For all intents and purposes, you've mutated the memory.
| Sure, you haven't mutated by reaching directly to the
| RAM. But the effect is still the same.
| nicoburns wrote:
| How is that any different to calling a function on a
| class? That's technically not class A modifying class B's
| memory either. B modifies it's own memory in response to
| a message (function parameters) from A. The message going
| over a network doesn't make that fundamentally different.
| staticassertion wrote:
| Function parameters aren't messages. They're shared
| state. I'd suggest watching the talk and reading about
| message passing systems in general.
| nicoburns wrote:
| I suppose if you mutate them. But we have a linter in
| place and a CI system that enforces it that prevents
| that.
| staticassertion wrote:
| There are many solutions, certainly. A network is one
| option, which I personally prefer, but as I said
| elsewhere it's a "choose the right tool for the job" kind
| of situation.
| blowski wrote:
| "Watch this famous video" is not a great response. Many
| of us watched it years ago and seem to have interpreted
| it rather differently.
| staticassertion wrote:
| Then you interpreted it incorrectly. I'm not inclined to
| teach you via HN about a subject that's well documented
| by resources I've already linked.
| a4isms wrote:
| > Fundamentally, microservices allow you to isolate state. I
| can take two services and split them up - and now I've split
| their state spaces. I can put a queue service between them
| and now I've sliced out the state of their communication.
|
| Dr. Alan Kay would like a word. This is literally the premise
| behind OO:
|
| > "OOP to me means only messaging, local retention and
| protection and hiding of state-process, and extreme late-
| binding of all things."--Dr. Alan Kay
|
| Outside of "extreme late-binding," which is a fascinating
| topic in its own right, isolating state is exactly the point
| of OOP. If we need microservices to accomplish isolation of
| state, that suggests we got OOP wrong, very wrong.
| geoffjentry wrote:
| > that suggests we got OOP wrong, very wrong.
|
| It does, but that's because there are different flavors of
| OOP. Alan Kay's original take on OO was closer to the actor
| model than what grew into the mainstream spin on OOP with
| inheritance and the rest.
|
| If you take 10 steps back and squint, microservices & the
| actor model start to look pretty similar.
| dimitrios1 wrote:
| So more like Erlang/OTP rather than Spring Boot
| Microservices?
| [deleted]
| staticassertion wrote:
| I'm extremely aware of Alan Kay's statement, as well as the
| foundations of the actor model. The reality is that today
| that is not what OOP has become, and Alan Kay would agree.
|
| > that suggests we got OOP wrong, very wrong.
|
| Alan Kay very clearly states that people "got it wrong" and
| that OOP was supposed to be about messaging. ie: He
| intended for it to be one thing, but it isn't that thing.
|
| > I'm sorry that I long ago coined the term "objects" for
| this topic because it gets many people to focus on the
| lesser idea. The big idea is "messaging"
|
| > The key in making great and growable systems is much more
| to design how its modules communicate rather than what
| their internal properties and behaviors should be. [..]
|
| http://wiki.c2.com/?AlanKayOnMessaging
|
| https://computinged.wordpress.com/2010/09/11/moti-asks-
| objec...
| geoffjentry wrote:
| > and that OOP was supposed to be about messaging
|
| I agree that these are Kay's thoughts and also agree with
| his take on what it should be. But I think the reality is
| more complicated than it simply being something that
| evolved away from his grand dream. It's more that there
| was a soup of ideas floating around during that time that
| came together as OOP and the combination that became
| dominant was something else. For instance Simula was
| already using inheritance prior to Kay's message passing
| proposal.
| staticassertion wrote:
| I can agree with all of that, I wasn't trying to imply
| otherwise, more just explaining that stating that OOP
| means what Kay wanted it to mean is ignoring history,
| consensus, and Kay himself.
| a4isms wrote:
| I'm very aware that we evolved things Kay may not have
| intended, and that doesn't make it wrong.
|
| He may have coined the term, but he doesn't own it, nor
| should we feel beholden to his vision dating back to
| 1972.
|
| What I said was _if_ the primary reason for micro
| services is hiding of state, _then_ we got OO wrong,
| because OO, even the much maligned J2EE style of OO, can
| do that for us if we want hiding of state and message
| passing.
|
| Another possibility is that microservices do much more
| for us than hiding of state and limiting communication to
| message-passing.
|
| At my 9-5, we use Elixir to write our services and have a
| few Actor-based Scala services too, so my feeling is that
| we actually are doing OO fine, and that there's something
| else that makes microservices compelling at scale.
| staticassertion wrote:
| What you said was that Kay would disagree, and that we
| must have gotten OO wrong otherwise. Kay wouldn't
| disagree and Kay would say we got OO wrong.
| a4isms wrote:
| What I said was:
|
| > If we need microservices to accomplish isolation of
| state, that suggests we got OOP wrong, very wrong.
|
| That's the last sentence, which summarizes my point.
|
| As for Dr. Kay, his exact words were saying that to him
| at the time OO was certain concepts and nothing more.
|
| I have never interpreted that to mean that languages or
| systems that do more than hiding state and message
| passing are wrong, just that if we say something like "OO
| requires inheritance," he would disagree with our
| definition of OO.
|
| After all... Smalltalk itself has a lot more than hiding
| of state and message passing. Would anyone claim that Dr.
| Alan Kay would say Dr. Alan Kay was doing OO wrong?
|
| I think there are good reasons to design microservice
| architectures, but if the argument is "Let's break up our
| monolith so we can hide state," I'd say that we can go
| ahead and just use our existing OO tools to achieve that.
| pixl97 wrote:
| Then I'll have to say that most get OOP very wrong, for
| example any time an application crashes for any reason.
| jimbokun wrote:
| > If we need microservices to accomplish isolation of
| state, that suggests we got OOP wrong, very wrong.
|
| I don't think there's any question about that.
|
| The only language that really seems to get this right is
| Erlang (and Elixir).
|
| And I suppose Smalltalk, but I don't think even Smalltalk
| takes it as far as the Erlang VM.
| seti0Cha wrote:
| Arguably, we did. In large codebases worked on by multiple
| teams it's not unusual to see teams drilling holes in OO
| walls because they "just want to get their work done" and
| view the abstractions as barriers. Taken along with the
| unfortunate fact that the majority of engineers suck at
| decomposing things into objects and the result is people
| preferring to move stuff out of process to keep the code
| simple and make the encapsulation more effective. I don't
| really think that's a good thing, but that's been my
| observation.
| a4isms wrote:
| Erlang/Elixir feels like it strikes a middle ground,
| where every process behaves like one of Kay's objects,
| including the emphasis on message-passing rather than
| methods that behave like procedure calls.
| [deleted]
| manigandham wrote:
| Network boundaries cause far more problems than they solve,
| and you've just shifted the complexity to now securing the
| network, usually with even more additional services, proxies,
| services meshes, firewalls, etc.
| staticassertion wrote:
| > Network boundaries cause far more problems than they
| solve,
|
| They cause exactly 0 extra problems. A call from function A
| to function B can fail due to B having a bug. A call from
| service A to service B can fail due to B having a bug or a
| network failure. Either way, failure is possible and has to
| be handled - the network only makes that more obvious.
|
| Further, a call between functions can cause mutated shared
| state - not the case across a boundary, they physically do
| not share mutable state.
|
| > and you've just shifted the complexity to now securing
| the network
|
| Not really. Fundamentally you have split your service
| capabilites up - now you can apply least privilege as you
| desire.
| nicoburns wrote:
| With a monolith you can put everything inside a database
| transaction and have a an entire request's worth of logic
| succeed or fail together. That's a lot easier to manage
| that having parts of the logic spread over multiple
| systems succeed and other parts fail.
| staticassertion wrote:
| So use transactions? I don't understand what part of
| microservices prevents that. In fact, transactions are
| pretty fundamental to reliable systems.
|
| https://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf
|
| From the abstract:
|
| >It is pointed out that faults in production software are
| often soft (transient) and that a transaction mechanism
| combined with persistent process-pairs provides fault-
| tolerant execution -- the key to software fault-
| tolerance.
| nicoburns wrote:
| Well you can't use database transactions across multiple
| connections, so presumably this would involve you
| implementing your own transaction and rollback system.
| That's a lot more complexity than using a system that
| just works out of the box.
| staticassertion wrote:
| I don't really understand. If I have a database, and a
| service is talking to it, it can open a transaction. If I
| then want to talk to other services, and rollback that
| transaction based on what happens with those, I can do
| that.
|
| Microservices changes nothing about this. If you want to
| remove transactions by splitting up your logic such that
| it operates in terms of sequences or something, you can
| do that, but that's just a choice like any other.
| nicoburns wrote:
| If the other services you talk to mutate state then
| rolling back those changes is non-trivial.
| convolvatron wrote:
| absolutely - if 'microservices' had transactions, it
| would actually provide some real leverage for fault
| handling over a monolith
| blowski wrote:
| You drop in "...or a network failure" like it's a rare
| occurrence that's easy to handle.
| staticassertion wrote:
| Frequency is irrelevant to the complexity. As I said, you
| _have_ to handle the idea of cross-boundary failures,
| such as with modules that have bugs.
|
| If you aren't taking steps to do so, you're not writing
| robust code.
|
| Anyway, yes, persistent network failures are rare for
| many people.
| ori_b wrote:
| Network calls can appear to fail, but actually succeed.
|
| Local function calls don't have to deal with byzantine
| failures[1].
|
| [1] https://en.wikipedia.org/wiki/Byzantine_fault
| staticassertion wrote:
| Function calls can, of course, fail with side effects.
| Idempotency is always a desirable property.
| travisd wrote:
| At some point, you can't gracefully handle bugs in other
| peoples code. If a function you call causes a SEGFAULT,
| in the vast majority of software, you're not expected to
| handle that. That's an invariant error, and you probably
| want some way to detect that it happened so you can fix
| it, but it's not reasonable to ask every caller of every
| function to handle that (in the same way we don't
| consider "the earth blew up" to be a reasonable thing to
| protect against, even though it its technically
| possible). There's simply not enough time and money to
| protect against every possible edge case in _most_
| software (NASA projects aside).
|
| The argument here is that network issues are exceedingly
| common in microservice environments and so aren't
| actually an edge failure case, so you actually have to
| worry about them way more than you would worry about a
| function in a different module causing a SEGFAULT.
| staticassertion wrote:
| The point is not to handle individual bugs, it is to
| handle all failures. This is the difference between a
| "defensive programming" approach and the "let it crash"/
| "zen of erlang" approach. Actors are designed such that
| they have failure isolation, which means they can react
| to errors in other actors without worrying about their
| own state. They then have _two_ options based on one of
| two bug classes - transient and persistent.
|
| Persistent errors are propagated to the supervisor.
| Transient errors are either retried or propagated.
|
| It doesn't matter if it's a network error, a disk error,
| a timeout, a crash, a cosmic radiation bit flip - your
| approach is always one of those two. So adding more
| failure cases doesn't "matter" in terms of your error
| handling, although you may want to adopt helpful patterns
| in the nuances of "retry".
|
| The frequency of errors will obviously increase with a
| network error (arguably very very little), but the
| pattern is fundamental to resiliency.
|
| If your network is truly so unreliable that you can not
| pay that cost, don't do it. I don't think most people are
| developing on networks that fail for long periods of time
| frequently.
| blowski wrote:
| > Frequency is irrelevant to the complexity
|
| So if something happens 50% of the time you should treat
| it in the same as if it happens one in 100 billion?
| staticassertion wrote:
| Maybe? I can't compare 50% to 100 billion. If your
| computer crashed every 100 billion instructions that
| would be a problem. If it crashed every other
| instruction, that would be very slightly more (or the
| same amount) of a problem.
|
| The point is that if you have a function call, you have
| the opportunity for a bug/ failure. Networks don't change
| that - you have the opportunity for a bug/ failure. The
| major difference is that services have stronger failure
| isolation.
| blowski wrote:
| It sounds like you're designing a very hypothetical bit
| of software.
| staticassertion wrote:
| As opposed to designing software that is already
| implemented?
| manigandham wrote:
| A failure is obvious all by itself. Network boundaries
| just turn it into a much bigger failure. And network
| failures are far more common and harder to test, handle
| and recover from.
|
| > _" Further, a call between functions can cause mutated
| shared state - not the case across a boundary, they
| physically do not share mutable state."_
|
| This is false as state is not tied to your process nor
| does it require a network leap to add isolation.
|
| > _" now you can apply least privilege as you desire."_
|
| How exactly? It's not magic, you still have to _apply_
| them, and now it requires more strategies and effort to
| accomplish.
| staticassertion wrote:
| I'm ignoring the first two points since I'm tired of
| explaining these things to people - you can read the
| papers/ watch the talks I've linked.
|
| > How exactly? It's not magic, you still have to apply
| them, and now it requires more strategies and effort to
| accomplish.
|
| Yes, we have tons of tooling for process isolation.
| Splitting a service into two services means you can
| isolate two processes instead of one, which means you
| break up the capabilities unique to each.
|
| I used the word "apply" so I don't know why you're saying
| "you still have to apply them"... it's literally what I
| just said.
| manigandham wrote:
| Securing the network is more work than just securing the
| code, because now there's a network in the way.
|
| For all the repetition you have on this thread, can you
| summarize it with the actual benefit that you have gained
| in a serious production use?
| staticassertion wrote:
| > Securing the network is more work than just securing
| the code, because now there's a network in the way.
|
| I very much disagree.
|
| > For all the repetition you have on this thread, can you
| summarize it with the actual benefit that you have gained
| in a serious production use?
|
| I already have summarized it. All I've done since is
| correct people being incorrect with regards to my
| summary.
|
| If you want a specific example, here's a blog post I
| wrote a long time ago (the dates are incorrect since we
| moved websites):
| https://www.graplsecurity.com/post/architecting-for-
| performa...
| rightbyte wrote:
| > Fundamentally, microservices allow you to isolate state.
|
| You can have logical dependencies between those "isolated"
| states anyway so I don't see that as a benefit really
| compared to say Java OOP private fields.
| dagss wrote:
| Re immutability -- I would say a well written backend in any
| language would (probably?) throw away the entire state
| between each request being handled. It's _possible_ to
| introduce state, sure, but why and how does that happen? For
| very many backends the only natural thing to do is to code
| them stateless, keep all the state is in the database, and
| each new request starts in a fresh world.
|
| I see two common sources of state in any backend (monolithic
| or not):
|
| 1) Caching, whether resources or flags, whitelists
|
| 2) Connection pools.
|
| If there are ever any issues with those they can be segmented
| inside a monolith for a fraction of the cost of going to
| microservices (either using the same boundaries as if you had
| split into microservices -- or other boundaries, like just
| one set of caches/connection pools per endpoint handler..)
|
| So I agree with the OP that the social aspect and development
| process is the only rational for microservices.
|
| Otherwise, just scale the monolith horizontally to the same
| number of instances and you have strictly more ways to
| partition state; microservices only give you one way to
| partition state that may not even be the best one.
| WookieRushing wrote:
| While isolation is important for managing state, the other
| side effect of isolation is allowing separate scaling of
| resources.
|
| If you can scale up your number of workers for a particular
| emergency then things get easier to handle.
| staticassertion wrote:
| It also makes bin packing services much simpler for that
| same reason.
| camgunz wrote:
| > Fundamentally, microservices allow you to isolate state.
|
| I think it's not really state isolation: your state is now
| spread across multiple separate services and a queue, which
| is objectively more complicated. To me, it's more the extreme
| version of things like dunder methods in Python or opaque
| structs in C: it prevents a specific type of programmer
| behavior. But honestly, it feels easier to solve this in code
| review.
|
| Like, I agree it's bad to reach behind the public API of
| something, but microservices aren't immune to this. I've
| never worked on a microservice architecture that didn't have
| weird APIs just to support specific use cases, or had a bunch
| of WONTFIX bugs because other services depended on the buggy
| behavior. That's not fundamentally different than "this super
| important program calls .__use_me_and_get_fired__": you have
| an external program dictating the behavior and architecture
| of your own.
|
| And you get multiple other layers of complexity here:
| networks, distributed transactions, separate dependency
| graphs, securing inter-server communications, auth/auth.
|
| I don't think you're entirely wrong--there's a lot of history
| looking at state as a series of immutable updates (Git,
| Redux), and I think it is harder to "cheat" in this way using
| microservices. I just think it's far from a clear win.
| strictfp wrote:
| Organizing around software components is such an idiotic idea.
|
| Good luck changing your design or making end-to-end features
| when you have teams protecting "their" part of the software.
|
| You've just made sure that any significant change to the system
| requires coordinating many different teams, making it at least
| one order more difficult than before, and a lot more
| bureaucratic.
| [deleted]
| folkhack wrote:
| For my anecdotal experience, microservices is the
| introduction of fiefdoms in development.
|
| And, I get it. Selfishly I would _love_ to come onto a
| project and only have to worry about net-new development. It
| is hard to learn, and then positively contribute within
| another engineered system... of any complexity. When it 's
| "my code" I tend to be much more productive, and it's easier
| to find my way through the forest.
|
| Anymore, everyone is on a power-grab for "my tools" and "my
| way" in regards to everything they're working on with near-
| zero attempt to understand the base needs of the
| business/feature. Microservices fill this need well as devs
| can work with their preferred toolset and just setup I/O
| boundaries for everyone else to use their service. Also, this
| is good for resume-driven development as you can often claim
| creation/ownership over some "piece" which looks way better
| on paper vs. "contributed to a big 'ol project."
|
| I'm not against microservices, I'm just being honest with how
| I've seen them socially play out - all of this is anecdotal
| to my experiences.
| dragonwriter wrote:
| > For my anecdotal experience, microservices is the
| introduction of fiefdoms in development.
|
| Fiefdoms, whether implicit or explicit, are pervasive in
| organizations beyond trivial size; IME, software
| architecture choices may impact the shape of the fiefdoms,
| but not their existence.
| [deleted]
| ChrisCinelli wrote:
| Microservices are not to scale organization even if some
| organizations used them in this way. There is a big problem
| with this way of scaling. The sense ownership becomes the sense
| of defend your castle (team's microservice code) from invasion
| (external developer that are trying to add features or fix
| bugs).
|
| Microservices were also presented as a solution for
| encapsulation. But if you cannot write good encapsulated code
| in a monolith, what makes you think microservices are the
| answer?
| http://www.codingthearchitecture.com/2014/07/06/distributed_...
|
| Microservices (or just services) are the solution of having
| more bandwidth for a set of features without having to more of
| everything else and preventing some part of the code to
| influence negatively some others.
| lamontcg wrote:
| A technology reason to have services is that you can have large
| RAM/SSD caches on services and move that data off of your front
| end monoliths, shrinking the footprint of the monolith and
| keeping more data accessible quickly (although small caches for
| the very hottest data might be good to retain on the first
| tier). That data probably shouldn't be peeled off though until
| there's a software team there to maintain the new service, and
| it should really be living in its own data pool on the backend
| (you shouldn't be writing a service to front a single database
| table, you should be writing a service to front an entire
| database). If the data is large enough and important enough to
| be moved to a service, and there's performance wins by doing
| so, and if there's a team that can manage that service, then it
| probably is a good idea. A single team that is managing a
| monolith busting it up into a dozen services that they still
| manage, and all the data comes out of a single database server
| is probably the wrong way to do it.
|
| There might be some other cases where you have hard business
| requirements and such for some software to be able to ship
| without other software and need to build clean lines and
| services so features can be extracted and probably some other
| edge cases, but the larger point should be that extracting the
| service should almost be demanded, both technologically and
| organizationally. If you have a choice and it isn't clear, then
| a service is probably the wrong thing. Services also really
| shouldn't be "micro" until you're an absolutely huge company
| and you can burn entire teams on small edge cases.
| papito wrote:
| Dropbox - monolith
|
| Instagram - monolith
|
| StackOverflow - monolith (at least until SO Enterprise)
|
| There are many others.
|
| There is a reason why we avoided "distributed systems" in the
| past. It's insanely hard. Microsevices solve some problems in
| _theory_ but create actual problems in practice.
|
| For most companies out there, distributed systems solve
| problems the companies don't even have. But, boy, do they need
| 10x more engineers to maintain this all.
| bin_bash wrote:
| Dropbox migrated to Go microservices
| papito wrote:
| Fair enough. At that scale it's different. My point is that
| many _major_ companies were a productive team working with
| a monolith until it simply was not feasible.
| jimbokun wrote:
| Yes, you always want to start with a monolith then break
| out micro services as the API, scaling and deployment
| strategies, and team sizes become clear from running in
| and scaling in production for a good while.
| hakre wrote:
| An they pose(d) some attraction. A boss after getting tired
| developing the baby that turned into a monolith and brought
| enough wealth to the table started to outline a new system
| with 12 or so microservices. Each one could be designed and
| planned and all written out in nice 2 to 6 page documents -
| one for each service.
|
| Now guess the size of the code wrangler team. And as this was
| so super-extravagant, guess the number of developers who were
| "promoted" to work on those micro-services.
|
| > But, boy, do they need 10x more engineers to maintain this
| all.
|
| Well stupidity saves you here. Ignore the one team per
| microservice rule and swap it with the "one-size-fits-it-all"
| developer rule: just promote one of the single team to be
| responsible for all micro-services. One lunatic that pushes
| code fast enough that management does not realize what is
| going on. Once everything is up and running, it just runs.
| The rest is downtime eventually, but you know what, its a
| software problem, what could be done? As long as everyone
| involved looks busy - and it's easy with plenty of micro-
| services to play whack-a-mole, bring one up again, kill two
| others, it is just a fail in the design as they should have
| been designed with failover but that was missed!
| jacobsenscott wrote:
| > A lot of people working on one code base over the top of each
| other often causes problems and issues with ownership.
|
| Microservices don't fix this. If I'm working on a feature in a
| monolith and I need to modify code someone else is also working
| on for some other feature that same situation would occur in a
| microservices based app. Just because the code is in a
| different git repo, and called with via an RPC doesn't change
| the fact that you need to change it.
|
| Most software is monolithic, and most critical software is
| millions lines of code that hundreds or thousands of people
| have worked on - all without using microservices.
| WalterBright wrote:
| Analogy is in programming itself - divide up a program into
| modules that each have a very clearly defined interface. Then
| people can work in parallel on it. I know everybody agrees with
| this, and it is stupidly obvious. But time after time, I see
| source file after source file importing (or #include'ing) every
| other module in the project. A pull request to fix a problem
| affects 10 files instead of one.
|
| It seems to me that people are simply terrible at modularizing
| code. (Including me.) I've seen this problem far more often
| than not, in every organization I've worked with, for my entire
| career.
|
| Just the other day I worked on a function that did some Windows
| API calls for file I/O, allocated a bunch of memory, and
| processed the file contents. I split it up so the code that
| needed the Windows API did just that - it didn't allocate any
| memory, and the processing was done with a callback.
|
| That meant the Windows API accessing code didn't need to import
| anything from the rest of the program, and the rest didn't need
| to import the Windows API.
|
| (There are some success stories. The popularization of generic
| algorithms and ranges (or iterators) has been a big
| improvement. And the use of global variables has become frowned
| upon.)
| nicoburns wrote:
| My experience has been a little better than yours. I've
| definitely worked on some spaghetti codebases, but I've
| worked on some really nicely modularised ones too.
| h2odragon wrote:
| > people are simply terrible at modularizing code.
|
| Once you realize you needed it, its too late.
|
| Then once you've been burnt on that fire for a bit, you go
| all out in designing the next few projects with framework and
| forethought and wind up with 100 lines of that for a 10 line
| script.
|
| the moral is "life's a bitch"
| 1penny42cents wrote:
| That oscillation is necessary to be able to converge on the
| optimal medium for any given problem.
|
| Otherwise we get stuck in "modularization bad" or
| "modularization good" mindsets, where both are wrong.
| dkarl wrote:
| I agree; people are much more careful about splitting
| responsibilities and designing APIs between processes (REST,
| GraphQL, XML-RPC) than between code modules. Simply switching
| from a monolith to microservices makes them more thoughtful
| about the consequences of design.
| dec0dedab0de wrote:
| _Microservices was always a solution to the organisational
| problem of getting more developers working on a system at
| once._
|
| It may be a solution, but there were already solutions for
| that. As far as I remember, the orignal argument of
| microservices was to allow different teams to use whatever
| languages/tools they choose, as long as they provided an API.
| As opposed to having IT, payroll, and sales all having to wait
| for one development team to make everything. Then with docker
| and containers it became that you could isolate deployments,
| and scale out just the parts that need it. Which is great if
| you need to minimize outages, and have some parts of your
| system that get major spikes in traffic, and you decide it's
| worth the extra complexity.
| blantonl wrote:
| This is where micro-services come in for me. Except, for all
| intents and purposes I'm a one man development shop.
|
| APIs.
|
| I've deployed about 10 or micro-services for use cases where
| a simple API is required for my applications. Maybe it's
| literally querying a row in a table and returning the result
| in JSON format. Or maybe it's to generate a JWT to access
| Apple Maps.
|
| Just craft it up in NodeJS, deploy to Lambda, and those
| little services haven't changed in _years_ but they just keep
| cranking away.
|
| We can have both monoliths and micro-services where
| appropriate.
| [deleted]
| mason55 wrote:
| At the risk of committing a "No True Scotsman" fallacy,
| what you're talking about is not really what people are
| talking about when they are discussing the tradeoffs of a
| microservices architecture.
|
| While "microservice" obviously literally means a small
| service, when people talk about microservice architecture
| they're usually talking about building out applications
| that look like a single service to the end-user but in
| reality are a whole bunch of small services that talk to
| each other.
|
| Just creating a small service that exposes a small piece of
| functionality is clearly the right thing to do in many
| cases, but that's not what the discussion about
| microservices architectures is really about.
| throwaway894345 wrote:
| I have a little website that I maintain personally and it
| consists of distinct services for auth, analytics,
| comments, and a fileserver for static HTML (also a bunch
| of cronjobs for backing up databases and so on). It runs
| on Kubernetes on a couple of Raspberry Pis in my office.
| These services are sort of distinct, but several
| collaborate with the auth service.
|
| Some would say this is overkill and they're probably
| right (although I would argue that it's not overkill to
| the degree that most on this forum would initially
| believe), but I haven't had any real issues with the
| microservice architecture; however, I do _like_ that each
| service has its own secrets--the comments service doesn
| 't have access to the auth service's private key or
| database credentials so if it gets pwned the blast radius
| is more limited. Similarly, I will be able to create
| network policies to lock these services down so they can
| only talk to their collaborators (defense in depth).
| Maybe there are some analogues in the Java or .Net VMs
| for these isolation techniques, but I don't think there's
| any general analog.
|
| That said, there is some amount of infrastructure
| overhead for each service (each service likely needs its
| own CD pipeline, DNS, letsencrypt certs, database, etc)
| but these are all managed via infrastructure as code so I
| can basically just stamp out these services with little
| effort.
|
| I have plans for NFS, mastodon, and media services all of
| which are third party and thus it wouldn't be desirable
| to integrate them into a monolith, but I'll be able to
| take advantage of my infrastructure as code automation to
| stamp out these services (which is mostly to say that
| "monolith" doesn't really absolve you from needing to
| manage many services anyway).
|
| In general, I've not had the sorts of problems that
| people complain about with respect to microservices with
| my personal project, nor with my work projects at various
| prior employers. I'm not sure what the difference is--
| maybe I've been graced with good architecture? That said,
| I _have_ worked on monoliths that were pretty bad
| experiences, and I think a big part of this was that it
| was too easy for teams to thoughtlessly extend the
| interfaces between components which degrades the
| architecture over time (conversely, I posit that
| microservices make it more difficult to change interfaces
| and thus there needs to be a more compelling reason).
| This is just speculation based on my experiences; I don
| 't intend for it to seem authoritative.
| sodapopcan wrote:
| Yes. I like to call these "regular-size services". Of
| course, it's just SOA.
| gowld wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once.
|
| Hmm? You can do that simply with API boundaries inside a
| program. Linux kernel has huge development team that compiles a
| all binary.
| jimbokun wrote:
| Mainly because for a very long time, Linus reviewed every
| pull request.
| CogitoCogito wrote:
| But that requires discipline.
| folkhack wrote:
| Discipline, leadership, organization, and, most of all:
| coherency between developers.
|
| Most orgs do not have these things - _especially_ not at
| the level of the Linux team. Also the motives of OSS are
| completely different than that of your typical business - I
| personally think this keeps OSS team coherent /productive
| for far longer than your typical corp can.
| gjulianm wrote:
| I think the Linux kernel is a special case. For starters, due
| to the nature of the kernel itself, a lot of components are
| very intertwined. You'll be hard pressed to find one area of
| the kernel core in which you can work without at least having
| an idea of how other parts work. But for other components,
| such as drivers, you'll find they're far more independent and
| different teams do work on them, and update them separately
| even in out-of-tree module builds, mimicking a bit how you'd
| do microservices in that limited setting.
| vlunkr wrote:
| So is every piece of large software a 'special case'?
| Besides the Linux Kernel, there's every other OS ever
| written, office tools, browsers, video games, all sorts of
| SaaS apps. The idea that microservices solve some problem
| in that space is bogus.
| gjulianm wrote:
| It is a special case because there's nothing underneath
| the kernel. Different pieces of the kernel usually cannot
| interact through anything that isn't the single binary,
| there aren't more levels of abstraction.
|
| But office tools, browser, video games, SaaS apps can
| benefit from the architecture. Microservices, at least
| for me, doesn't mean "different processes running in
| containers on AWS", but separate "services" that can be
| run and deployed independently. One easy example is login
| components, say any of those tools offers the possibility
| to the user to login with one or more remote services.
| Instead of putting that code in the same monolith, you
| could have a separate binary that gets called by the
| parent and spits out an authorization token. The separate
| binary can be tested, developed and updated separately.
|
| Of course, you can't apply microservices to everything
| and have it make sense, but the ideas of separate tools
| deployed and updated independently are not bogus. I mean,
| the Unix philosophy could be understood as a kind of
| microservices architecture, with different independent
| tools managed by separate teams.
| vlunkr wrote:
| > the ideas of separate tools deployed and updated
| independently are not bogus
|
| No, but the idea that you should do that because you have
| a big team is bogus. There are good reasons to break some
| applications up into services, and this is the least
| compelling one.
| gjulianm wrote:
| I think that having an architecture matching your
| organization is not that much of a bad idea. If the
| organization consists of multiple independent teams with
| different managers, deadlines and priorities, what would
| be easier? An architecture with separate, isolated
| services that communicate over some established APIs and
| can be updated, tested and deployed independently, or a
| monolith where just to release a new version you have to
| get all the teams to agree on it?
| hakre wrote:
| IMHO you should still take it the other way round.
|
| What Conway wrote: You can use the development of the
| software as one tool to learn about the social
| interactions in the organization.
|
| Only doing microservices and then saying: Hey look, this
| matches our organization is offering very little overall.
|
| So what if the different managers, their deadlines and
| priorities is the cause of many more problems not only
| the wrong decision to do micro-services (exemplary)?
| emaginniss wrote:
| No every other OS: https://www.gnu.org/software/hurd/
| jayd16 wrote:
| You can use microservices to decouple things like deployment
| schedules, build dependencies, configurations, etc.
| breakalot wrote:
| You mean "duplicate"?
| theamk wrote:
| Sure you can, and then you have a team that introduced a bug
| in common library that caused 100% CPU consumption on all
| cores, and tests did not caught it so somehow got into
| production.
|
| In the monorepo world, your whole system is broken, it is all
| hands on board to try to fix this, everyone is stressed out.
|
| In the microservice world, you have only one microservice
| which went down, so most teams don't have to worry.. in the
| worst case, they'll say: "Sorry, but we depend on service X
| and they are down.. blame them, nothing we can do". Sure,
| that team which introduced the bug is stressed, but the
| average company stress is much lower.
|
| Having a successful monorepo requires organized, cohesive
| team with good communications -- or at least a team with a
| highly experienced people with veto power (this is the Linux
| kernel model). Unfortunately, a lot of real-life businesses
| do not have it.
| hakre wrote:
| > In the monorepo world, your whole system is broken, it is
| all hands on board to try to fix this, everyone is stressed
| out.
|
| No, not at all. And the kernel is a single repo even.
|
| > In the microservice world, you have only one microservice
| which went down, so most teams don't have to worry....
| blame them, nothing we can do
|
| Well how is that better than just switching the dependency
| back to last known version and ship instead being dependent
| on a whole different team just to get dependencies fixed
| _and_ running.
|
| > Unfortunately, a lot of real-life businesses do not have
| it.
|
| That may be true, however benefit of those properties are
| in different kind of development projects, and this is not
| the question of whether monolith or microservices IMHO.
| Also not mono repo or non-source binary distribution.
| seti0Cha wrote:
| > In the microservice world, you have only one microservice
| which went down, so most teams don't have to worry..
|
| My experience has been that one service going down (or even
| running slowly) can lead to cascading failures where
| identifying the root cause is a slow painful process. I
| know that in a well designed system that doesn't happen,
| but that's the nature of all bugs, isn't it?
| theamk wrote:
| Well yes, you still need monitoring to be able to tell
| that the failure is external, but the key idea is that
| each team can do it separately, without having to get
| everyone's buy-in, or instrumenting every call in the
| system.
|
| For example, we've had a batch processing system, with
| pretty relaxed latency requirements, and at some point we
| were asked to integrate with (internal) service X. The
| problem is, service X which would go down periodically.
| The solution was pretty simple: a simple centralized
| error logging service we already had, some asserts on
| results, and timeout on all HTTP calls. This works very
| well, for us at least. The service X still goes down
| every once in a while, but we can always detect that and
| explain to our (internal) customers that it is not our
| fault the system is down. Our customers were the ones who
| selected service X in the first place, so they are pretty
| understanding.
|
| Is it a desirable situation to be in? Nope, in the ideal
| case, someone would go to team behind service X and help
| them to make service X reliable, with proactive
| monitoring, good practices, more staffing, etc... But I
| work are in the big org, and each team has its own
| budget, management and priorities. So the microservices
| approach is the best we can do to still get the work done
| under such conditions.
| papito wrote:
| And microservices do NOT require an organized, cohesive
| team with good communication?
|
| If anything, there is MORE communication.
|
| And how many teams who do distributed systems really know
| what will happen if a critical service goes down? The
| system is down - same effect.
| jimbokun wrote:
| The communication is in terms of well defined and
| documented APIs. Which having micro service boundary
| strongly enforces.
|
| > The system is down - same effect.
|
| Yes if it's a service many other services depends on, but
| not so much if it's near the leaves of the service
| dependency tree. In which case the system may still be up
| with reduced functionality.
| matchagaucho wrote:
| But also, according to Conway's Law, you end up with a product
| with leaky abstractions that reveal the underlying micro-
| services and org structure.
| billiam wrote:
| >It is easier to start with a monolith, find the right design
| and then split on the boundaries than it is to make the correct
| microservices to begin with.
|
| Not pleasant, but true.
| jbluepolarbear wrote:
| A better solution would be to build modules independently and
| have a single service use each module. Then things are unified,
| each team has a client it must deliver to, and issues must be
| fixed in order for them to be released in the final product.
| How are microservices better? Often each service is out of sync
| with each other, one service will upgrade and break another,
| that's not possible with a single source and multiple modules.
| pixl97 wrote:
| Do people not version their API requests?
| jbluepolarbear wrote:
| Yep and it gets worse, you'll have teams add new breaking
| features or deprecate features without letting the other
| team know. Hey their tests pass so what do they care. I've
| worked with both strategies and modules over microservices
| are easier to integrate, ensure integrity, and reduces the
| probability that stuff breaks in production. Often
| microservices develop to a set of requirements and never
| consider the client that will be using that service. With
| modules that can't happen.
| breakalot wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once.
|
| Wasn't Continuous Integration (CI servers) created long ago to
| solve that?
|
| Where developers can test and release their own changes,
| incrementally, without stepping on each other toes?
|
| What is next?
| Espressosaurus wrote:
| CI helps releasing fast, it doesn't do anything about not
| stepping on each other's toes. You can imagine a case where
| two people are working on the same part of the codebase and
| having merge conflicts everywhere. CI doesn't help with that,
| though it does make it a little bit less stressful to resolve
| those conflicts.
|
| Microservices forces boundaries, which in turn allows you to
| scale the number of teams to the number of service boundaries
| and now you're no longer stepping on each other.
|
| With the disclaimer that I'm an embedded programmer so I
| don't have a dog in this fight, my reading of the literature
| suggests it's best seen as an organizational tool rather than
| a performance tool.
| TheCoelacanth wrote:
| > In software engineering, continuous integration (CI) is
| the practice of merging all developers' working copies to a
| shared mainline several times a day. [1]
|
| That certainly does help with avoiding conflicts. There are
| only so many conflicts that you can pick up in a few hours
| of work.
|
| [1] https://en.wikipedia.org/wiki/Continuous_integration
| outworlder wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once
|
| In other words, it's a great way to ship your org chart.
|
| I've only ever seen a handful of examples where the
| microservice boundaries were set regardless on how the actual
| teams are organized in the reporting structure.
| icambron wrote:
| You'll ship your org chart whether you try to or not. There
| are two questions: a) will you architect your software to
| make this process (relatively) efficient? and b) to what
| degree are you willing to change your org chat to improve
| your architectural boundaries?
| mwcampbell wrote:
| I think one can control the degree to which software
| architecture reflects the org chart. To take an extreme
| example, Chrome is primarily a single, giant (~200 MB)
| binary. I'm sure the layout of the source repositories
| reflects the Chrome org chart. But thankfully, they always
| had the engineering discipline to produce the architecture
| that was best for performance (a monolith, albeit a multi-
| process one) without letting it get out of control.
| anon23anon wrote:
| Feel like the conversation went something like this - - We need
| this thing done by <insert date> -- That's impossible - What if
| we hire more ppl? -- They'd just step over each other - Let's
| divide things up then -- ok
|
| * six months pass by * - why isn't it done yet? -- we had to
| onboard and train all those new hires which sucked up a lot of
| dev time plus the new architecture added complexity and
| increased communication costs - How can we make our onboarding
| process faster?
|
| * sigh and the cycles repeats it self
| aloisdg wrote:
| "What one programmer can do in one month, two programmers can
| do in two months." Fred Brooks
| chronofar wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once.
|
| I'm not sure that that's entirely true. To be sure that's an
| aspect, but it's also conceptually quite reasonable to desire
| the best tool for a particular job rather than employ a kitchen
| sink for everything. Separation of concerns is a commonly
| admired quality in code, and it makes sense sometimes to have
| this separation be at the repo level.
|
| I don't jive with the "only organizational not technical"
| characterizations this thread is rife with. It's now hipster to
| say the cool shiny thing is lame, and it blinds some utility.
|
| > It is easier to start with a monolith, find the right design
| and then split on the boundaries than it is to make the correct
| microservices to begin with.
|
| This I definitely agree with in many, perhaps most, cases. But
| of course inertia, especially in organizations, could have
| future you lamenting such a decision you now have no easy way
| out of.
| logifail wrote:
| > It is easier to start with a monolith, find the right design
| and then split on the boundaries [..]
|
| This reminds me of the discussion on _let pedestrians define
| the walkways_ [0] [1]
|
| "As time goes on, we get smarter. We learn more about ourselves
| or our customers -- what we or they really want. Therefore,
| we're at our dumbest at the beginning, and at our smartest at
| the end. So when should you make decisions? When you have the
| most information, when you're at your smartest: as late as
| possible."
|
| [0] https://sive.rs/walkways [1]
| https://www.theguardian.com/cities/2018/oct/05/desire-paths-...
| dragonwriter wrote:
| > Microservices was always a solution to the organisational
| problem of getting more developers working on a system at once.
|
| Microservices was always a solution to the problem that SOA got
| swallowed by "implementing XML heavy standards" and lost
| attention to it's architectural principles.
|
| (SOA was originally, and microservices a return to, a solution
| to reusing components and isolating faults so you need _fewer_
| , not _more_ , developers and support personnel dedicated to
| any given system or collection of systems.)
| hintymad wrote:
| Not sure if this story is true: Okta used to have a monolith
| architecture on AWS. All their 300 engineers used to work on
| the same service, so they had to run all their tests for every
| commit. The cost? $60 per commit.
| cellis wrote:
| Sounds pretty cheap, relative to 300 engineers.
| samwillis wrote:
| Assuming a dev is committing (ball park) 4 times per day,
| that's in the region of $55k/year per developer, or
| $16.5M/year all in. Thats not cheap...
| cellis wrote:
| You only need to run CI on Production, and you can squash
| commits. Generally a release is once per week, and at
| Oktas level you have a release engineer.
| samwillis wrote:
| Yes, I suppose I could be taking the anecdote too
| literally. It's much more likely they are only running
| all test on push to main / against pull requests / on
| code review.
| TheCoelacanth wrote:
| 300 developers' work being crammed together into a weekly
| release without having their contributions pass CI first
| sounds absolutely hellish for whatever poor bastard has
| to track down who broke the build.
| nicoburns wrote:
| There's tooling like bors that will rollup commits
| together and run CI on them before merging to master. If
| it fails then the commits will be retried individually.
| ar_lan wrote:
| 4 commits per day per developer is exceptionally high,
| unless these are tiny, tiny changes.
|
| I'm a very productive engineer on my team and I average
| less than 1 commit per day.
| djur wrote:
| I would not assume that 300 developers are all committing
| 4 times a day. That seems very high.
| jimbokun wrote:
| And there you have it...$60 per commit means slowing down
| your commit velocity! Which means its longer before
| changes get tested or reviewed or deployed.
|
| The cost (money and more importantly time) of running
| tests fundamentally changes the development process.
| xorcist wrote:
| More commits are not better.
| theamk wrote:
| That's what, 15 minutes of FTE salary+overhead?
|
| Sounds pretty reasonable.
| samwillis wrote:
| 60x4x8x5x48 = $460,800/year full time salary+overhead?
|
| I'm not sure that's right.
| theamk wrote:
| That's $230K year and 100% overhead
|
| Sure, $230K a year is on the high side, but Okta is
| headquartered in SF, so it is plausible.
|
| I cannot find a documented source for overhead, but in
| private conversations multiple people told me that 100%
| is pretty reasonable amount, and often is even higher.
| hibikir wrote:
| When your system is critical enough, those kind of prices are
| cheap for what you get.
|
| I can't tell you about Okta, but there used to be a (now
| apparently gone) article by Nelson Elhague about their test
| parallelization infrastructure. Many thousands of pretty slow
| test ran for every Jenkins build, massively parallelized
| across machines to get an acceptable response time. At the
| time he wrote this, there was no modularization to speak of,
| so every test really had to run for every build. Very
| expensive, but there's a lot of value on getting the
| equivalent of integration-level tests for almost every
| critical system automatically.
|
| As a monorepo grows, the technologies used have to change to
| make its disadvantages spiral out of control: Serious
| modularization of codebases, something like Bazel to make
| sure code isn't overbuilt, and a testing strategy that finds
| the right balance of finding problems and keeping expenses in
| control. Every company with a monorepo ends up walking that
| road, but the good part is that by the time you have a
| problem, you definitely have proof that your organization is
| in a situation where the problem is worth solving.
|
| This is very different from, say, what I saw at a company
| that had Fred George as CTO, and was going all in on
| microservices with one customer and about a dozen engineers,
| all of which wrote in the same JVM language. At that point,
| all the work that avoids running too many tests is probably
| going to be a net loss, and even more so when one considers
| opportunity costs.
| sleepybrett wrote:
| ... when your pipeline architecture becomes more of a cost
| sink that development into your actual product.
| pbreit wrote:
| Where I've found "microservices" to be sensible is where you
| have multiple different clients to power (ie, website, iOS &
| Android). They all consumer the same JSON and render natively.
|
| Otherwise, microservices just turn what was once easy into very
| complicated.
| asim wrote:
| It's just about need. Most people don't need microservices. Let
| me repeat that. Most people don't need microservices. It's only
| relevant at scale. The scale I'm talking about is organizational
| scale and then potentially technical scale but it's mostly about
| solving people problems by enabling independent development of
| products and features.
|
| Developers are their own worst enemy. They love shiny buzzwords
| and using unnecessary tools and concepts just to say they did.
| Conceptually you can't blame architecture patterns, that makes no
| sense. Blame those who choose to adopt patterns for the wrong
| reasons.
| phendrenad2 wrote:
| The monolith vs microservice debate always seemed so misguided to
| me. It seems exactly like vim vs emacs. Or ruby vs python. The
| arguments are always the same.
|
| * "In vim I can do this in 3 keystrokes, in emacs it takes 5!"
| (where "this" is some vim-idiomatic thing you'd never do in
| emacs).
|
| * "Ruby leads to bad programs, I have inherited a legacy ruby
| codebase and you wouldn't believe what they did..." / "Python
| leads to bad programs, I have inherited a legacy python codebase
| and you wouldn't believe what they did..."
|
| * My team took a python/ruby app and rewrote it ruby/python, and
| now it's 99% faster and our productivity is way higher!
|
| What I'm hinting at is this: You can write a bad or good
| microservice or monolith. The rules are different. You'll have
| different frustrations and tradeoffs. You'll have to play to the
| architecture's strengths and avoid it's weaknesses. You'll NEED
| institutional standards to keep people from doing the wrong thing
| for the architecture model and making a mess.
| rr808 wrote:
| Single RDMS database + stateless middle tier is still best
| solution for 99% of applications out there.
| jollybean wrote:
| Would you agree that caching fits into notion of 'stateless' ?
| rr808 wrote:
| Yeah as long as has very little complexity.
| folkhack wrote:
| Agree.
|
| But even fighting for RDMS in 2022 is getting daunting as so
| many people will immediately start pushing for document DB's,
| GraphQL, etc. Seriously - I feel like SWE's have no idea the
| powerhouse a modest MySQL/Postgres instance can crank out while
| perfectly maintaining their data (ACID, replication, etc).
|
| Everyone wants to use tools that were designed for FAANG scale
| regardless of org size. Anecdotally I've fought this hard
| because it's almost always at incredible detriment to the
| business's needs.
|
| I find that modern devs balk at "single RDMS database +
| stateless middle tier" but only for selfish reasons like
| resume-driven development. This pattern is really burning me
| out more than anything else of my career.
|
| Again, all this is personal anecdotes.
| jghn wrote:
| I've found the largest culprit here is that people don't
| understand how many orders of magnitude are between them and
| FAANG scale. It's akin to how people don't understand the
| difference between a millionaire, a billionaire, and Elon
| Musk.
|
| So they'll see some numbers that are on the upper end or
| beyond what they're used to seeing, and to them that's big
| scale. How do you solve that? Well, you reach for the tools
| other people have used when _they_ have "big scale". All the
| literature says you can't just increase your instance size
| when you have big scale, so why would you try that?
|
| And yes, that's wrong. But it drives a lot of the mentality.
| [deleted]
| dvirsky wrote:
| There is another aspect to this - if you're working on a
| startup that will scale, if successful - not to FAANG
| scale, but let's say many millions of DAUs and thousands of
| QPS on the servers - you also want to build some kind of
| future proofing into your architecture.
|
| And then begins the dance of balancing what we currently
| need (we have maybe 100K DAU and launched recently) and
| what we predict we might need if things go right. So you
| don't need to go full on K8S with some crazy sharded
| database and 50 microservices on day 1, but you also don't
| want a PHP/MySQL monolith if you're building something that
| works like, say, Twitter, because you'll have to scrap ALL
| of that under huge pressure if things start to take off.
| folkhack wrote:
| > 100K DAU
|
| > but you also don't want a PHP/MySQL monolith if you're
| building something that works like, say, Twitter
|
| This is a lot of whiplash in regards to discussing size.
|
| I just want to say...
|
| 100K DAU with a PHP/MySQL monolith is 100% possible - I'm
| certain a lot of people here have achieved this without
| much problem. Things like Nginx, PHP-FPM, reverse-proxy-
| caching, load balancing to stateless application servers,
| read replica, offloading static assets to CDN, blah
| blah... I digress but you can 100% hit 100K DAU with a
| traditional PHP/MySQL monolith.
| ativzzz wrote:
| Could not disagree more. If you are a startup that is
| struggling to survive, it is an absolute waste of
| resources to overengineer your app for potential scale.
| It's the VC way to burn all of the money hiring talented
| infra engineers to manage this, but it is not pragmatic
| at all. The exception is if your startup is literally a
| high volume data processing platform or something
| similar.
|
| That simple PHP/MySQL or rails monolith will scale much
| further than you think by throwing more servers at it
| without having to hire an army of devops engineers.
| Solving problems you don't currently have when your
| company is not profitable is a waste of money.
| mwcampbell wrote:
| Maybe the monolith shouldn't use PHP and MySQL. But what
| about, say, a high-performance managed runtime (e.g. JVM
| or CLR) and SQLite? Expensify's findings [1] suggest that
| with vertical scaling, SQLite can go very far.
|
| [1]: https://blog.expensify.com/2018/01/08/scaling-
| sqlite-to-4m-q...
| bsder wrote:
| "If you have to ask if you have big data, you don't have
| big data. When you have big data, you _know_ you have big
| data. "
|
| Seriously, you can launch a server that has almost a
| terabyte of RAM! Is your business doing enough to make that
| database even blink? "My sources say no".
| dalyons wrote:
| i have worked on several not-faang-sized-but-largish b2c
| startups, all of which were forced to spend a very large
| amount of money, time and people trying to migrate things
| off the one central RDBMS when it could no longer be scaled
| vertically. This is a real problem that you likely will run
| into well before FAANG size, and it really does hurt, and i
| think it gets minimized by the "just use one postgres for
| everything" trope. You should probably think about it at
| least a little if your planned business trajectory is into
| the 1 million+ users realm.
|
| Im not saying you have to use nosql or whatever, but some
| sort of small future proofing (eg introducing different
| schemas/permissions for your different data domains inside
| your monolith) can help make future database seperation
| much easier.
|
| If you're doing a B2B app its a different story, much
| harder to hit the limits of a big RDS instance.
|
| The real answer, as in most software engineering is "it
| depends"
| dagss wrote:
| Micro-services is about partitioning based on
| functionality and features -- so I think more often than
| not, 99% of the microservices use 10% of the storage and
| 1 microservice use 90% of the storage, and you're back to
| solving the problem of horizontally scaling your storage
| regardless of microservice vs monolith.
| dalyons wrote:
| thats sometimes true, not always. but a good observation.
| Even if it is true, having that 90% usecase behind its
| own service often allows a lot more flexibility to scale
| for that particular storage problem , and not have to use
| it generically/everywhere. Eg, time-partioning, cold
| archiving, sharding, whatever is suitable for just that
| use case.
| mwcampbell wrote:
| How long ago did these startups hit the limits of
| vertical scaling? Those limits are always increasing.
| Expensify's famous post from 2018 [1] suggests that it
| should be feasible for one monster machine to handle
| millions of concurrent users.
|
| [1]: https://blog.expensify.com/2018/01/08/scaling-
| sqlite-to-4m-q...
| dalyons wrote:
| theres one that im still working on today :) for
| practical and all the other usual reasons most people are
| going to rent cloud dbs (like RDS), not run bare metal.
| Also, theoretical/benchmark performance is a very long
| way away from the actually achievable performance when
| you have 100s of developers actively evolving a codebase
| against the database. Optimal query usage etc in that
| scenario is an impossible pipe dream, best you can do is
| "not crazy", unless you grind all development to a halt
| behind gatekeeping dba-types.
|
| There are many other operational challenges to single
| very large database instances. Upgrades, backups,
| migrations, etc all become way more risky and hard when
| you get into the mega-db range. The number of total
| outages ive seen caused by migrations gone awry, query
| plans gone awry... RDBMS are incredibly complicated
| beasts and at huge sizes can be very unpredictable in a
| way that many smaller dbs are not.
| folkhack wrote:
| kristianpaul wrote:
| Then boring technologies are no that bad after all, imho at the
| end it's about facing changes quickly and if you have the tools
| and systems to do that then good !
___________________________________________________________________
(page generated 2022-05-10 23:01 UTC)