News for hackers. Stuff that matters.
Re:Give me back my monolith (2019) by manigandham on Tuesday May 10, 2022 @01:54PM (#31330165)
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.
Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @03:03PM (#31331184)
> 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.

Re:Give me back my monolith (2019) by manigandham on Tuesday May 10, 2022 @05:16PM (#31332833)
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.

Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @05:27PM (#31332951)
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.

Re:Give me back my monolith (2019) by manigandham on Tuesday May 10, 2022 @05:35PM (#31333034)
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?

Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @05:49PM (#31333172)
> 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...

Re:Give me back my monolith (2019) by manigandham on Wednesday May 11, 2022 @12:34PM (#31342316)
The only potential benefit there was for security, specifically because of your security-based product and the async nature of its processing. And even that was just relying on the ephemeral nature of lambdas instead of other security constructs or simply resetting instances of a monolith to accomplish exactly the same thing.

Nothing in that article explained a clear need or benefit of microservices.

Re:Give me back my monolith (2019) by staticassertion on Wednesday May 11, 2022 @02:21PM (#31343840)
> because of your security-based product

Nothing in the article has to do with the product or the fact that it's security related, other than to provide a motivating use case.

> The only potential benefit there was for security

And performance.

> even that was just relying on the ephemeral nature of lambdas

I think you've failed to understand the article, which may be my fault, I haven't read it in a long time. The key is isolation. Ephemerality gives you a sort of temporal isolation. Splitting your messaging from your data storage gives you a capability based isolation. And so on.

It also means we can scale to the limits of S3/SQS - each service is itself stateless, the majority of state is managed in SQS, which could be quite loose about its consistency since every service is idempotent - arguably a form of temporal isolation.

What I've described in this article is effectively the actor model. I feel like I don't have to really justify the benefits of the actor model with regards to scale?

Re:Give me back my monolith (2019) by manigandham on Wednesday May 11, 2022 @11:42PM (#31349036)
actor model != microservices.

What part of microservices (split functionality with completely separate runtime artifact deployed to separate servers) is needed for actors? You can have actors in a monolith.

Re:Give me back my monolith (2019) by staticassertion on Thursday May 12, 2022 @03:00PM (#31358693)
No part of microservices is needed for actors and I didn't imply that at all. I said that microservices can be easily modeled as actors.
Re:Give me back my monolith (2019) by nicoburns on Tuesday May 10, 2022 @03:35PM (#31331586)
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.
Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @03:38PM (#31331631)
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.

Re:Give me back my monolith (2019) by abraxas on Tuesday May 10, 2022 @10:00PM (#31335026)
So distributed transactions with two phase commit, XA and all that. Imagine what, microservices hipsters tried that and it turned out too slow and cumbersome so they invented "sagas" which are still immensely more complex than a single transaction in a single database.
Re:Give me back my monolith (2019) by staticassertion on Wednesday May 11, 2022 @02:23PM (#31343854)
You seem confused. If you want a transaction use a transaction. If you don't want a transaction don't use a transaction. If you need a transaction across services, that sounds like you've run across a microservice antipattern. Monolith/Microservice changes nothing here - you can have the same issue in a monolith where two different functions are managing transactions and now you want a single transaction.

Literally irrelevant.

Re:Give me back my monolith (2019) by nicoburns on Tuesday May 10, 2022 @04:21PM (#31332158)
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.
Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @04:29PM (#31332258)
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.

Re:Give me back my monolith (2019) by nicoburns on Tuesday May 10, 2022 @06:19PM (#31333410)
If the other services you talk to mutate state then rolling back those changes is non-trivial.
Re:Give me back my monolith (2019) by staticassertion on Wednesday May 11, 2022 @07:58AM (#31338599)
Well... don't do that? This is where microservices comes in. In a SOA architecture nothing really tells you when it's a good idea to split things up. Microservices is a methodology to help you avoid this exact situation.

You'd have the same problem in a monolith if you have two different modules working on the same db.

Re:Give me back my monolith (2019) by dagss on Wednesday May 11, 2022 @01:54AM (#31336272)
Assume you have two tables A and B on the same DB. They are sort of seen as unrelated. Suddenly a feature request requires that A and B are mutated together consistently.

If it is in one service you just use a common DB transaction and get it done.

If it is in one microservice for A and one microservice for B then you have to somehow implement this transaction yourself. This is possible but more work.

Re:Give me back my monolith (2019) by staticassertion on Wednesday May 11, 2022 @02:24PM (#31343871)
OK imagine that you have two different modules that manage transactions to a database. Now suddenly you need there to be consistent mutations between those functions.

Do you see my point? Microservices do nothing here - you have run into antipatterns that are universal, and that microservice architecture addresses explicitly as an antipattern.

Re:Give me back my monolith (2019) by dagss on Thursday May 12, 2022 @10:02AM (#31354331)
I do not see your point. Sometimes consistent mutations between modules is wanted. Monoliths lets you do it. Perhaps you discovered your module boundaries were wrong, you create a supermodule to encaspulate both to coordinate the joint transaction and then split up later a different way and so on.

Module boundaries are refactorable.

Importantly, what if the alternatives you end up with achieve the same things with microservices end up causing a ball of mud of services, reimplementing transaction logic that belong in your DB in your homegrown network protocols?

You seem to say that some things are not possible with microservices and therefore this leads to cleaner code. My retort is that the kind of things one sometimes come up with as workarounds to make things still work for microservices are so complex that the cure is worse than the disease you wanted to cure in the first place.

Re:Give me back my monolith (2019) by staticassertion on Thursday May 12, 2022 @04:11PM (#31359610)
> Module boundaries are refactorable.

Why are microservices not refactorable? This is the same exact issue in both cases. You designed something for a use case, the use case changed, now your old design isn't working. So maybe you merge those two services, or merge those two modules, or whatever else you want to do.

> reimplementing transaction logic that belong in your DB in your homegrown network protocols

Don't do that? I mean, again, this issue of "I wrote something the wrong way and now I have to fix that" is not any better or worse in microservices.

> My retort is that the kind of things one sometimes come up with as workarounds to make things still work for microservices

That doesn't sound like microservices. In fact, even the idea of having a database shared across services doesn't sound like microservices - it's an explicit antipattern. So it sounds like a bad SOA design. The point of microservices is to take SOA and add patterns and guidance to avoid the issues you're talking about.

Re:Give me back my monolith (2019) by dagss on Thursday May 12, 2022 @04:24PM (#31359748)
Microservices gets owned by different teams, teams get cemented, politics get in the way of refactoring. Game over.

Sure, if you are a single team working on 10 microservices you can probably refactor with abandon without spending 70% of your working days in meetings talking about migrations and trying to sync strategies...

You may have experiences that that microservices are as easy to refactor as monoliths; in my experience it is orders of magnitude harder...

I think there is a bit of a "No true scotsman" fallacy at play here. You see something you do not like then it is "not microservices done properly".

How about state all the things you don't like about monoliths , then I say "that is not monoliths done properly", "don't do that" for each one?

I think both monoliths and microservices can lead to good code or balls of mud depending on the organization and developers involved.

Real question isn't whether "microservices done right" is better. The question is: does a Decision to do microservices reduce the chances of a ball of mud, when that Decision is then implemented by imperfect developers in an imperfect organization?

PS I always meant that each microservice had their own DB above, we agree on that and I never dreamt otherwise.

What I was getting at is that when you go distributed, sometimes quite complex patterns must be applied to compensate.

You may say the architecture is then "better", but on what metric? It is certainly more work up front -- so you start out in the negative and to become better the system and organization need at least to get to a certain scale, you need to save in the hours you invested to come out ahead.

In many scenarios the cost in developer-months needed up front is just as important as other factors in evaluating the best architecture. E.g. a scrappy startup simply should not do it IMO. Corporations..... perhaps;but I have seen it gone badly. (I guess it is just not "done right" then? See above.)

Re:Give me back my monolith (2019) by dagss on Thursday May 12, 2022 @05:02PM (#31360090)
PS I think microservices excel in making people FEEL productive (doing work that is not directly benefiting the company).

I have personal experience with the same product built twice, once as a monolith by a small team that worked really well and once as lots of services.

The featureset and development speed is about the same, but the many-services requires 10x as many people.

However by splitting into many services everyone feels productive doing auxiliary and incidental work. Only those of us who worked on the first system are able to see that the total output of the company is the same but 10x as expensive.

Re:Give me back my monolith (2019) by staticassertion on Thursday May 12, 2022 @06:30PM (#31360870)
> Microservices gets owned by different teams, teams get cemented, politics get in the way of refactoring. Game over.

I don't understand how microservices make this worse in any way. Modules get owned by different teams all the time.

> You may have experiences that that microservices are as easy to refactor as monoliths; in my experience it is orders of magnitude harder...

Yes, I have said before that I believe merging is fundamentally simpler than splitting. If we're just talking about merging a module vs a service, I don't believe either is harder than the other - I mean... nothing about microservices prevents you from using modules, and indeed I would highly recommend it.

> I think there is a bit of a "No true scotsman" fallacy at play here. You see something you do not like then it is "not microservices done properly".

For sure, and that's a failing of microservices. People think microservices means "SOA", or "write a lot of services". If you want to criticize SOA or whatever, sure, the argument of "don't do that" goes away.

> How about state all the things you don't like about monoliths , then I say "that is not monoliths done properly", "don't do that" for each one?

I probably could state a bunch of things that are pretty fundamental, but I don't think it's important - I don't know that I've actually said anywhere that microservices are better than monoliths, what I've instead said are the benefits of microservices that I see, which others have taken to mean that I somehow think monoliths or modules are bad.

> You may say the architecture is then "better"

I honestly don't think I've said that anywhere, or even made a judgment anywhere.

I think I can summarize, again, what I've said.

1. Network boundaries provide a physical layer that enforces isolation of state and the use of message passing

2. Isolation of state makes scaling a system easier

3. Isolation of capabilities makes securing a system easier

4. SOA inherently leverages the network boundary

5. Microservice Architecture is similar to SOA but with a bunch of patterns, guidance, and concepts that you leverage in your design

What I've received in response is a hodgepodge of:

1. "Modules can isolate state" - only true in some languages, and even then there's no physical barrier enforcing it, you're relying on developers to maintain that isolation.

2. "But what if you do anti-patterns that microservices tell you not to" - ok, that's why microservice architecture has books and documentation about what not to do. If you do those things, I'm not going to blame you, it's a failing of all methodologies when users have a hard time understanding them.

But so far the anti-patterns mentioned aren't really compelling or specific to microservices. You wrote code to satisfy a domain, the domain changed, now you need to change that code so that it satisfies the new domain. That happens all the time, merging services isn't any harder than merging modules.

3. General misunderstandings about state, security, etc.

> What I was getting at is that when you go distributed,

I'm not really convinced that "distributed" is the right word here. People talk about distributed systems being complex, and I think they're confused - what's complex is consensus, but splitting one service from another service shouldn't impact consensus, and the fact that they're now located on two different assets does not necessarily make things more complex.

Those services may be more complex, if your application was quite trivial - a totally stateless system with no external connections, for example. I see no reason to rewrite 'grep' as a microservice, and I would never recommend that.

Those services may now be more error-prone because you have things like dns, tcp, etc involved. If you don't want to make that tradeoff, that's OK, you could be right in that case. Again, no need to make all software be microservices.

(Going to respond to your other message here)

> PS I think microservices excel in making people FEEL productive (doing work that is not directly benefiting the company).

Maybe, I don't really know. It isn't my experience, but that's just me. Most developers seem to be pretty bad at their jobs so I imagine that all sorts of issues can be experienced. Certainly the idea of rewriting a monolith as a microservice seems like a red flag unless there were very specific needs.

Re:Give me back my monolith (2019) by convolvatron on Tuesday May 10, 2022 @04:28PM (#31332249)
absolutely - if 'microservices' had transactions, it would actually provide some real leverage for fault handling over a monolith
Re:Give me back my monolith (2019) by blowski on Tuesday May 10, 2022 @03:24PM (#31331450)
You drop in “…or a network failure” like it’s a rare occurrence that’s easy to handle.
Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @03:29PM (#31331507)
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.

Re:Give me back my monolith (2019) by travisd on Tuesday May 10, 2022 @03:46PM (#31331725)
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.

Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @03:54PM (#31331838)
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.

Re:Give me back my monolith (2019) by kaba0 on Tuesday May 10, 2022 @07:35PM (#31334016)
But now you are talking squarely about Erlang actors, not microservices in general. The runtime gives you all the needed guarantees here.
Re:Give me back my monolith (2019) by staticassertion on Wednesday May 11, 2022 @07:59AM (#31338616)
I talk about services and actors interchangeably because there's no interesting differences between them.
Re:Give me back my monolith (2019) by kaba0 on Wednesday May 11, 2022 @05:02PM (#31345717)
Other than automatic handling of network exceptions, safe failiures and the shitton of other features Erlang runtimes have?
Re:Give me back my monolith (2019) by staticassertion on Thursday May 12, 2022 @04:12PM (#31359619)
I'm not sure what you're talking about. What automatic handling of network exceptions? What safe failures? BEAM has lots of great features, no question, but they have very little to do with the implementation of actors - BEAM primarily provides names and linking as useful primitives.
Re:Give me back my monolith (2019) by ori_b on Tuesday May 10, 2022 @04:19PM (#31332139)
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

Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @04:31PM (#31332280)
Function calls can, of course, fail with side effects. Idempotency is always a desirable property.
Re:Give me back my monolith (2019) by blowski on Tuesday May 10, 2022 @03:30PM (#31331523)
> 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?

Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @03:34PM (#31331556)
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.

Re:Give me back my monolith (2019) by blowski on Tuesday May 10, 2022 @03:42PM (#31331668)
It sounds like you’re designing a very hypothetical bit of software.
Re:Give me back my monolith (2019) by staticassertion on Tuesday May 10, 2022 @04:03PM (#31331951)
As opposed to designing software that is already implemented?