Live data from Hacker News

The costs of microservices (2020)

robertovitillo.com

191–200 of 410 posts

Re: The costs of microservices (2020)

#191

Earlier quoted context omitted.

I guess the GP's issue is because automated tests (and every other kind of validation) imposes architectural constraints on your system, and thus are an exception to your rule. I don't think that rule can be applied as universally as you stated it. But then, I have never seen anybody breaking it in a bad way that did also break it in a good way, so the people that need to hear it will have no problem with the simplif…

Hm. I think maybe you're using "system" to mean a different thing than I am? I thinking of "the system" as the thing that is executing in production - it provides the business behavior we are trying to provide; there is a larger "system" surrounding it, that includes the processes and engineers, and the CI/CD pipelines - it too has an "architecture", and _that_ architecture gets (moderately) more complex when you add…

> I think maybe you're using "system" to mean a different thing than I am?

No, I'm not. Are you overlooking some of the impacts of your tests and most of the impact of static verification?

Those do absolutely impact your system, not only your environment. For tests it's good to keep those impacts at a minimum (for static verification you want to maximize them), but they still have some.

Re: The costs of microservices (2020)

#192
The biggest negative of Microservices is that it creates hard ownership boundaries.

This affects planning - more effort is needed to understand boundaries that need adjustment or crossing.

This affects execution - needing to cross a boundary comes with inefficiencies and an automatic need to move with synchronization.

This affects future projects - service boundary clarity works against flexibility.

Re: The costs of microservices (2020)

#193

If a monolith is well-factored, what is the difference between it and co-located microservices? Probably just the interface - function calls become RPC. You accept some overhead for some benefits of treating components individually (patching!) What is the difference between distributed microservices v.s. co-located microservices? Deployment is more complex, but you get to intelligently assign processes to more optima…

Monolith->microservice is not a trivial change no matter how well-factored it is to begin with -- though being poorly architected could certainly make the transition more difficult!

> Probably just the interface - function calls become RPC.

This sounds simple, but once "function calls become RPC" then your client app also needs to handle:

* DNS server unreachable

* DNS server reachable but RPC hostname won't resolve

* RPC host resolves but not reachable

* RPC host reachable but refuses connection

* RPC host accepts connection but rejects client authentication

* RPC host presents untrusted TLS cert

* RPC accepts authentication but this client has exceeded the rate limit

* RPC accepts authentication but says 301 moved permanently

* RPC host accepts request but it will be x seconds before result is ready

* RPC host times out

Even for a well-factored app, handling these execution paths robustly probably means rearchitecting to allow you to asynchronously queue and rate limit requests, cache results, handle failure with logarithmic back-off retry, and operate with configurable client credentials, trust store, and resource URLs (so you can honor 301 Moved Permanently) and log all the failures.

You'll also need additional RPC functions and parameters to provide data that had previously been in context for local function calls.

Then the monolith's UI may now need to communicate network delays and failures to the user that were impossible before network segmentation could split the app itself.

Refactoring into microservices will require significant effort even for the most well built monolith.

Re: The costs of microservices (2020)

#195
post #84

I think people get the modularity wrong. Modularity is important, but I came to conclusion there is another important architectural principle, which I call "single vortex principle". First, a vortex in a software system is any loop in a data flow. For example, if we send data somewhere, and then we get them back processed, or are in any way influenced by them, we have a vortex. A mutable variable is an example of a r…

This is a very good point, and you could probably write quite a few articles about this particular subject. You may even have a service A that calls service B that calls service C that calls service A. Then you have a problem. Or, you have C get blocked by something happening in A that was unexpected. Ideally, you only have parents calling children without relying on the parents whatsoever, and if you fail in this, you have failed in your architecture.

Re: The costs of microservices (2020)

#196

Earlier quoted context omitted.

Also, DRY is not about repeated code. This drives me crazy. Ruby developers love to make code worse by trying to "DRY it up".

What are you replying to? The article is about how Dry shouldn't be over applied. Dry is literally "Don't Repeat Yourself" and is definitely pushed for cleaning up redundant code, so it's not unreasonable for people to think that's what about. It's only recently that people have pointed out that there's a difference between Duplicated code and Repeated code.

Redundant code is not code that looks the same. It's only reasonable for people to believe it is about code that looks the same if they have never bothered to learn what it means.

Re: The costs of microservices (2020)

#197
post #185

> And think of the sheer number of libraries - one for each language adopted - that need to be supported to provide common functionality that all services need, like logging. This is the #1 reason we quit the microservices game. It is simply a complete waste of mental bandwidth to worry about with the kind of tooling we have in 2023 (pure cloud native / infiniscale FaaS), especially when you have a customer base (e.g…

No one says you can't have all of your microservices use the same language...

Absolutely. This is how we operated when we were at the peak of our tech showmanship phase. We had ~12 different services, all .NET 4.x the exact same way.

This sounds like it could work, but then you start to wonder about how you'd get common code into those 12 services. Our answer at the time was nugets, but we operate in a sensitive domain with proprietary code, so public nuget services were a no go. So, we stood up our own goddamn nuget server just so we could distribute our own stuff to ourselves in the most complicated way possible.

Even if you are using all the same language and patterns everywhere, it still will not spare you from all of the accidental complexity that otherwise becomes essential if you break the solution into arbitrary piles.

Re: The costs of microservices (2020)

#198
post #84

I think people get the modularity wrong. Modularity is important, but I came to conclusion there is another important architectural principle, which I call "single vortex principle". First, a vortex in a software system is any loop in a data flow. For example, if we send data somewhere, and then we get them back processed, or are in any way influenced by them, we have a vortex. A mutable variable is an example of a r…

I find this vortex concept interesting. Do you have any books or online sources that I could use to study this?

It’s called engineering. /s

Re: The costs of microservices (2020)

#199
post #87

I recently had some discussions and did some research on this topic and I feel like there is a lot people don't talk about in these articles. Here are some more considerations between micro services and monolothic tradeoffs. Its also important to consider these two things as a scale and not a binary decision. 1. Isolation. Failure in on service doesn't fail the whole system. Smaller services have better isolation. 2.…

1. Isolation With a well built monolith, a failure on a service won't fail the whole system. For poorly built microservices, a failure on a service absolutely does being down the whole system. Not sure I am convinced that by adopting microservices, your code automatically gets better isolation

I work on low code cloud ETL tools. We provide the flexibility for the customer to do stupid things. This means we have extremely high variance in resource utilization.

An on demand button press can start a processes that runs for multiple days, and this is expected. A job can do 100k API requests or read/transform/write millions of records from a database, this is also expected. Out of memory errors happen often and are expected. It's not our bad code, its the customer's bad code.

Since jobs are run as microservices on isolated machines, this is all fine. A customer(or multiple at once) can set up something badly, run out of resources, and fail or go really slow and nobody is effected but them.

Re: The costs of microservices (2020)

#200

Earlier quoted context omitted.

Hm. I think maybe you're using "system" to mean a different thing than I am? I thinking of "the system" as the thing that is executing in production - it provides the business behavior we are trying to provide; there is a larger "system" surrounding it, that includes the processes and engineers, and the CI/CD pipelines - it too has an "architecture", and _that_ architecture gets (moderately) more complex when you add…

> I think maybe you're using "system" to mean a different thing than I am? No, I'm not. Are you overlooking some of the impacts of your tests and most of the impact of static verification? Those do absolutely impact your system, not only your environment. For tests it's good to keep those impacts at a minimum (for static verification you want to maximize them), but they still have some.

I don't think I'm overlooking any major ones, but we are probably working in quite different types of systems - I'm not aware of any type of static verification I'd use in a rails application that would affect _architecture_ in a meaningful way (unless I would write quite terrifying code without the verifier I suppose).

I'm not sure about the tests - it depends on what you'd consider an impact possibly; I've been trained by my context to design code to be decomposable in a way that _is_ easily testable, but I'm not sure that is really an 'impact of the tests' (and I'm fairly confident that it makes the abstractions less complex instead of more).

Would you mind explaining what you mean in more detail?

Post reply on HN