Live data from Hacker News

Monolith First (2015)

martinfowler.com

301–310 of 356 posts

Re: Monolith First (2015)

#301
post #266

Earlier quoted context omitted.

And apparently distributed RPC is ‘microservices’. I think we can all agree that straw man architectures don’t work. Everyone should employ the true Scotsman architecture.

It is how a large majority of microservices gets implemented in practice. What was originally a package, gets its own process and REST endpoint, sorry nowadays it should be gRPC, the network boilerplate gets wrapped in nice function calls, and gets used everywhere just like the original monolith code. Just like almost no one does REST as it was originality intended, most microservices end up reflecting the monolith w…

Okay, but if you’re allowed to submit ‘well structured modular componentized librarified monolith’ as an example proving how monoliths aren’t all bad, I’m not going to let you insist on holding up ‘cargo cult grpc mess’ as proof that microservices are terrible. Let’s compare the best both structures have to offer, or consider the worst both enable - but not just compare caricatures.

Re: Monolith First (2015)

#302
post #266

Earlier quoted context omitted.

It is how a large majority of microservices gets implemented in practice. What was originally a package, gets its own process and REST endpoint, sorry nowadays it should be gRPC, the network boilerplate gets wrapped in nice function calls, and gets used everywhere just like the original monolith code. Just like almost no one does REST as it was originality intended, most microservices end up reflecting the monolith w…

Okay, but if you’re allowed to submit ‘well structured modular componentized librarified monolith’ as an example proving how monoliths aren’t all bad, I’m not going to let you insist on holding up ‘cargo cult grpc mess’ as proof that microservices are terrible. Let’s compare the best both structures have to offer, or consider the worst both enable - but not just compare caricatures.

On the contrary, as the sales speech at conferences is that the mess only happens with monoliths and the only possible salvation is to rewrite the world as microservices.

Good programming practices to refactor monoliths never get touched upon, as otherwise the sale would lose its appeal.

Re: Monolith First (2015)

#303

IMO this is an unnecessary dichotomy that we're currently forced to deal with, because we don't yet have a good solution for programming the "cloud" the same way you program a for a single computer, and that ends up leaking into all the consequent decisions of modularisation, performance, code management, deployment, team organisation, etc. (My holy grail would be programming for distributed environments as if you ha…

> programming for distributed environments as if you had one giant single-thread computer, and function calls could arbitrarily happen over IO or not

Ex-Amazon SDE here. Message-passing libs like 0mq tried to push this idea.

They never became very popular internally because passing data between green threads vs OS threads vs processes vs hosts vs datacenters is never the same thing.

Latencies, bandwidths and probability of loss are incredibly different. Also the variance of such dimensions. (Not to mention security and legal requirements)

Furthermore, you cannot have LARGE applications autonomously move across networks without risks of cascading failures due to bottlenecks taking down whole datacenters.

Often you want to control how your application behaves on a network. This is also a reason why OTP (in Erlang or implemented in other languages) is not popular internally.

Re: Monolith First (2015)

#304
post #174
post #31

Earlier quoted context omitted.

When the same practices used to sell microservices get applied to modules, packages and libraries, there is no need to put a network in the middle to do the linker's job. But too many are eager to jump into distributed computing without understanding what they are bring into their development workflow and debugging scenarios.

> there is no need to put a network in the middle to do the linker's job. Absolutely. More people need to understand the binding hierarchy: - "early binding": function A calls function B. A specific implementation is selected at compile+link time. - "late binding": function A calls function B. The available implementations are linked in at build time, but the specific implementation is selected at runtime. From this…

You didn’t continue far enough down the hierarchy to find the places where microservices actually work. Honestly if you’re just calling a remote endpoint whose URL is embedded in your codebase and with the hard coded assumption that it will follow a certain contract you’re not moving down the binding hierarchy at all - you ‘re somewhere around ‘dynamic library loading’ in terms of indirection.

It gets much more interesting when you don’t call functions at all - you post messages. You have no idea which systems are going to handle them or where... and at that point, microservices are freeing.

All this focus on function call binding just seems so... small, compared to what distributed microservice architectures are actually for.

Re: Monolith First (2015)

#305
post #71

Hahaha. I have been saying the same for years but have either been punished by my managers or mercilessly downvoted on HN. Somehow mentioning that microservices might not be perfect solution in every case triggers a lot of people. I have actually helped save at least one project in a huge bank which got rolled from 140 services into one. The team got also scaled down to third of its size but was able to work on this…

I can understand Résumé-Driven Development. Our industry is famous for its "Must have (X+2) years of (X year old technology)" job requirements.

Re: Monolith First (2015)

#306
post #31

Earlier quoted context omitted.

When the same practices used to sell microservices get applied to modules, packages and libraries, there is no need to put a network in the middle to do the linker's job. But too many are eager to jump into distributed computing without understanding what they are bring into their development workflow and debugging scenarios.

I've been trying to get buy-in from colleagues to have stricter boundaries between modules but without much success, mainly because I don't fully understand how to do it myself. Let's say we have 3 different modules, all domains: sales, work, and materials. A customer places an order, someone on the factory floor needs to process it, and they need materials to do it. Materials know what work they are for, and work kn…

You need a thin layer on top that coordinates your many singular domains. We use graphql to do this. API Gateway or backend for frontend are similar concepts. Having many simple domains without any dependencies is great, they just need to be combined by a simple with many dependencies - a coordination layer.

Joining on the database layer is still adding a dependency between domains. The data models still need to come out of one domain. Dependencies add complexity. So joining is just like importing a module, but worse because it's hidden from the application.

If you really need a join or transaction, you need to think as if you had microservices. You'd need to denormalize data from one domain into another. Then the receiving domain can do whatever it wants.

Of course, you can always break these boundaries and add dependencies. But you end up with the complexity that comes with in, in the long run.

Re: Monolith First (2015)

#307
post #100

Earlier quoted context omitted.

But the network is so slooooooowwwwwwwww. Don't get me wrong, sometimes it's worth it (I particularly like Spark's facilities for distributed statistical modelling), but I really don't get (and have never gotten) why you would want to inflict that pain upon yourself if you don't have to.

This. One million times this. I’ve been developing for more years than dime if you have lived, and the best thing I’ve heard in years was that Google interviews were requiring developers to understand the overhead of requests. In addition, they should require understanding of design complexity of asynchronous queues, needing and suffering from management overhead of dead letter, scaling by sharding queues if it makes…

Indeed! The "Latency Numbers Every Programmer Should Know" page from Peter Norvig builds a helpful intuition from a performance perspective but of course there's a lot larger cost in terms of complexity as well.

Re: Monolith First (2015)

#308
post #296

The problem with creating a dichotomy between "monolith" and "microservices" is that... well... it doesn't make any sense. You describe your "microservices" and I'll explain how it's really just a monolith. "So let me get this straight, you have a Billing package and an Ordering package. How are these organized again?" -> "We have a distributed system." "So you you compile them together and deploy them horizontally a…

> "Ah, so you have two monoliths?" Made me snort.

Divide and conquer is all well and good, but it often ends up being:

A: We have a problem. I know, we'll use divide and conquer! Runs off.

B: Uh, that's actually Banach-Tarski^W^Wmicroservices? Wait, come back!

later

B: Now we have two problems, contorted to fit into a spherical subspace^W^WIO monad, and a dependency on the axiom of choice^W^W^Wasyncio library.

A: Wait, why are there monads? This is Javascript!

B: There are always monads, it's just a question of whether you type system is overengineered anough to model them.

Re: Monolith First (2015)

#309

IMO this is an unnecessary dichotomy that we're currently forced to deal with, because we don't yet have a good solution for programming the "cloud" the same way you program a for a single computer, and that ends up leaking into all the consequent decisions of modularisation, performance, code management, deployment, team organisation, etc. (My holy grail would be programming for distributed environments as if you ha…

> programming for distributed environments as if you had one giant single-thread computer, and function calls could arbitrarily happen over IO or not Ex-Amazon SDE here. Message-passing libs like 0mq tried to push this idea. They never became very popular internally because passing data between green threads vs OS threads vs processes vs hosts vs datacenters is never the same thing. Latencies, bandwidths and probabil…

I don't dispute one might want to have this control. At the same time, I don't see a theoretical reason one can't have the same programming model, and choosing what computation runs local vs. distributed is just a configuration. A function call or a remote call won't change the domain logic, it's an implementation detail - but today, this leaks into all kinds of decisions, starting from microservices and working backwards to glue everything together again.

Re: Monolith First (2015)

#310

I work for a small company that uses microservices architecture. The product is simple where a user registers, enters preferences, selects from courses and submits a form. A monolith would be doable with 5 good engineers. Instead we have about 50 engineers+QA releasing bug filled code. The company's design philosophy is based more on what is fashionable that what is suitable.

Anec-contra-data: I worked for a while at a small startup, initially as the sole developer and eventually growing to 3. We had an architecture I would describe as at least being "microservices-esque": a single large "monolithic" backend service, with a number of smaller consumer services, webapps, UIs. The distinction between microservices and monoliths may be debatable but I believe monoliths as described by Martin…

We currently have this approach. One graphql backend-for-frontend server in front of an arbitrary number of BE servers. The UI always has a consistent interface and the BE can focus on its business logic instead of how the FE should display it. The two layers can change fairly independently. We're still early in the project, but in theory I love this architecture and would use it again.
Post reply on HN