Live data from Hacker News

Modules, not microservices

blogs.newardassociates.com

351–360 of 671 posts

Re: Modules, not microservices

#351
On the subject of modules, I often recommend “Composite / Structured Design” and/or “Reliable Software Through Composite Design” by Glenford Myers.

It’s old. The examples are in PL/I. But his framework for identifying “Functional Strength” and Data Coupling is something every developer should have. Keep in mind this is before functional programming and OOP.

I personally think it could be updated around his concepts of data homogeneity. Interfaces and first class functions are structures he didn't have available to him, but don’t require any new categories on his end, which is to say his critique still seems solid.

Overall, most Best Practices stuff all seem either derivative of or superfluous to this guy just actually classifying modules by their boundaries and data.

I should note, I haven't audited his design methodologies, which I'm sure are quite dated. His taxonomy concerning modules was enough for me.

"The Art of Software Testing" is another of his. I picked up his whole corpus concerning software on thriftbooks for like $20.

Re: Modules, not microservices

#352

Earlier quoted context omitted.

A line is a unit of change that git can report on. If it's a separate file that is scoped to some specific concern, sure. But its tgat grouping by concern that is key. Not separation into another file. Extracting ra dom bits of code into separate files would be _worse_.

> A line is a unit of change that git can report on. Yes and no. Git doesn't store lines, it stores files. Git diff knows how to spit out line changes by comparing files. So to run git blame on a 10k line file you're reading multiple versions of that 10k file and comparing. It's slow. Worse still is that trying to split said file up while trying to preserve history won't make the git blame any faster.

Yes and yes. While agree with the general points, note that they didn't say "unit that git stores", but "unit git can report on". Git can totally report on lines as a unit of change.

Re: Modules, not microservices

#353

I think most criticisms around microservices are about good practices and skills beating microservices in theory. And the virtue of microservices is that they create hard boundaries no matter your skill and seniority level. Any unsupervised junior will probably dissolve the module boundaries. But they can't simply dissolve the hard boundary of having a service in another location.

I always love that circular logic.

"Hey our developers can't make modules correctly! Let's make the API boundaries using HTTP calls instead, then they'll suddenly know what to do!"

And that unsupervised junior? At one place I joined, that unsupervised junior just started passing data he "needed" via query string params in ginormous arrays from microservice to microservice.

And it wasn't a quick fix because instead of using the lovely type system that TELLS you where the stupid method has been used, you've got to go hunting for http calls scattered over multiple projects.

All you've done is make everything even more complicated, if you can't supervise your juniors, your code's going to go sideways whatever.

Microservices don't solve that at all and it's pure circular logic to claim otherwise. If your team can't make good classes, they can't make good APIs either. And worse still, suddenly everything's locked in because changing APIs is much harder than changing classes.

Re: Modules, not microservices

#354
post #330

Earlier quoted context omitted.

yes, it's very common design. sometimes called a "distirbuted monolith." it's not microservices because the number of additional services is usually small, and the codebase is still tightly coupled to itself (even if well factored in terms of modules). i.e., everything is still tested together, and there's still a single monolithic build and deployment process, and no team can go off and decide to write a service in…

so for example in the context of Java, you have one main App/main() entry, probably bounding to a port (let's say 80 serving HTTP requests) acting as a router it brokerages them to subclasses/handlers for CRUD/RPC/plumbing to database/other services then in a separate process App/main() you have a cron job or a queue of some sort you bundle these together as a monolith into one main()?

In the case of Java, imagine we have a big Maven project that has a bunch of different well factored modules that form the "libraries" of our application. At first, in our Maven project we also have a single module which is the deployable for "the monolith" -- it consumes all the other "lib" modules and gets packaged into a fat jar.

We deploy a few instances of the monolith fronted by a load balancer. There's not much scaling logic here -- when we see p75 request latency reach a certain threshold, we add another monolith instance.

A while later, we realize that the /foo route is getting a ton of spikey traffic, which makes it hard to scale. So, in the load balancer, we set up a new pool that just targets /foo, and in our Maven project we create a new module that will be the deployable for this pool. Now, /foo still requires most of our libs, so the jar we're bundling is still "the monolith" in essence, but maybe it doesn't require a few dependencies, and so is a little slimmer. We deploy that and everything is scaling great!

Then, we discover that in our main monolith, the background threads we were using to send emails are getting really clogged up, which is adversely effecting performance. We decide we want to move this work to an external persistent queue, like Kafka. Now, for our consumer, we create one more Maven module for a new jar. This time, we're lucky. Emails only need 2 of our libraries and so this is actually a pretty small deployable, but it's still being built from the same core set of libraries as the monolith.

Re: Modules, not microservices

#355

Earlier quoted context omitted.

This has been my major criticism of them; you cement the design of the app by creating an organizational structure around your software components. What happens if you need to redesign the architecture to meet new needs? That's right; it's not going to happen, because people will fight it tooth and nail. You also cannot produce any meaningful end-user value without involving several teams. Microservices is just "back…

How do you organize teams if not around services? As the GP points out, the whole point of SOA is to scale people. Yes, this makes rearchitecture hard, but that is always the case at scale. The problem of territoriality and resistance to change needs other solutions (tldr; clueful management and mature leadership level ICs who cut across many teams to align architecture vision and resolve disputes between local staff…

Organize teams around products. The point is to increase value delivered to the customer through the product, not to produce left-pad-as-a-service.

Re: Modules, not microservices

#356
post #72

Microservices, while often sold as solving a technical problem, usually actually solve for a human problem in scaling up an organization. There's two technical problems that microservices purport to solve: modularization (separation of concerns, hiding implementation, document interface and all that good stuff) and scalability (being able to increase the amount of compute, memory and IO to the specific modules that n…

I just want to point out that for the second problem (scalability of CPU/memory/io), microservices almost always make things worse. Making an RPC necessarily implies serialization and deserialization of data, and nearly always also means sending data over a socket. Plus the fact that most services have some constant overhead of the footprint to run the RPC code and other things (healthchecking, stats collection, etc.) that is typically bundled into each service. And even if the extra CPU/memory isn't a big deal for you, doing RPCs is going to add latency, and if you get too many microservices the latency numbers can start really adding up and be very difficult to fix later.

Running code in a single process is MUCH lower overhead because you don't need to transit a network layer and you're generally just passing pointers to data around rather than serializing/deserializing it.

There are definitely some cases where using microservices does make things more CPU/memory efficient, but it's much rarer than people think. An example where you'd actually get efficiency would be something like a geofence service (imagine Uber, Doordash, etc.) where the geofence definitions are probably large and have to be stored in memory. Depending on how often geofence queries happen, it might be more efficient to have a small number of geofence service instances with the geofence definitions loaded in memory rather than having this logic as a module that many workers need to have loaded. But again, cases like this are much less common than the cases where services just lead to massive bloat.

I was working at Uber when they started transitioning from monolith to microservices, and pretty much universally splitting logic into microservices required provisioning many more servers and were disastrous for end-to-end latency times.

Re: Modules, not microservices

#357
Idk I feel like one of the benefits to uservices is isolation; not in design or architecture as many comments say, but isolation from one service affecting another.

If I run a monolith and one least-used module leaks memory real hard, the entire process crashes even though the most-used/more important modules were fine.

Of course it's possible to run modularised code such that they're sandboxed/resources are controlled - but at that point it's like...isn't this all the same concept? Managed monolith with modules vs microservices on something like k8s.

I feel like rather than microservices or modules or whatever we need a concept for a sliding context, from one function->one group of functions->one feature->one service->dependent services->all services->etc.

With an architecture like that it would surely be possible to run each higher tier of context in any way we wanted; as a monolith, containerised, as lambdas. And working on it would be a matter of isolating yourself to the context required to get your current task done.

Re: Modules, not microservices

#358
I don't think microservices are the answer to everything, but I don't see how monoliths can keep up with developer velocity when an organization reaches thousands of developers.

Monoliths are way slower to deploy than microservices, and when you have hundreds or thousands of changes going out every day, this means lots of changes being bundled together in the same deployment, and as a consequence, lots of bugs. Having to stop a deployment and roll it back every time a defect is sent to production would just make the whoe thing completely undeployable.

Microservices have some additional operational overhead, but they do allow much faster deployments and rollbacks without affecting the whole org.

Maybe I am biased, but I would love an explanation from the monolith-evangelist crowd on how to keep a monolith able to deploy multiple times a day and capable of rolling back changes when people are pushing hundreds of PRs every day.

Re: Modules, not microservices

#359
post #72

Microservices, while often sold as solving a technical problem, usually actually solve for a human problem in scaling up an organization. There's two technical problems that microservices purport to solve: modularization (separation of concerns, hiding implementation, document interface and all that good stuff) and scalability (being able to increase the amount of compute, memory and IO to the specific modules that n…

I very much agree with you on points 1 & 2. I'll add a 3rd - drying up repeated functionality such as repeated auth logic in completely separate applications.

Re: Modules, not microservices

#360
post #72

Microservices, while often sold as solving a technical problem, usually actually solve for a human problem in scaling up an organization. There's two technical problems that microservices purport to solve: modularization (separation of concerns, hiding implementation, document interface and all that good stuff) and scalability (being able to increase the amount of compute, memory and IO to the specific modules that n…

This has been my major criticism of them; you cement the design of the app by creating an organizational structure around your software components. What happens if you need to redesign the architecture to meet new needs? That's right; it's not going to happen, because people will fight it tooth and nail. You also cannot produce any meaningful end-user value without involving several teams. Microservices is just "back…

Without the organizational benefits of a microservice you are just just making intermodular calls really slow, and fail intermittently.
Post reply on HN