Live data from Hacker News

Why Segment Went Back to a Monolith

infoq.com

201–210 of 328 posts

Re: Why Segment Went Back to a Monolith

#201
post #105

Are there any case studies where microservices went well? From an end user perspective, Netflix runs in “constantly degraded” mod. From an engineering perspective, they track “number of successful stream starts”, instead of percentage of the time 100% of their services are working. That’s a huge red flag. As a researcher, the monitoring and fault-propagation / modeling work they’ve done to get it to stay up at all is…

If the question "are there any case studies where microservices went well" is a valid question, then so must be, "are there any case studies where monolithic architecture went well".

My point being that if and only if we have a track record as an entire field of making decisions based on case studies, AND if case studies have a track record of being objective rather than proffered as a result of a marketing agenda, then the question is ultimately legitimate.

There are more shops by total count that fail with monolithic architecture. That's inevitable just based on the infinitesimal number of projects executed as service architectures rather than monoliths at large in the wild. But still, we carry on with monolithic architectural style as if its outcomes were assured.

It's far easier for the vast majority of developers to build a monolith because it allows development to proceed without having to have any knowledge of or practice with the tricks and traps of distributed systems - an entire body of knowledge that a developer might never get meaningful and practical exposure to for an entire career.

The trouble starts when microservices are attempted by developers who can't imagine that there are entire bodies of software development knowledge that developers aren't presently in possession of.

Microservices is just, as Adrian Cockroft used to say, "Service-Oriented Architecture with bounded contexts".

Web development is absolutely not a preparatory course in service oriented architecture. But the vast majority of web developers who attempt to take on SOA while simultaneously presuming an omniscience in all things software development due to their experiences only with monolithic web development will often fail to build a SOA. They usually end up with something that isn't quite SOA and isn't quite a monolith. And that's where the failures largely come from.

I work exclusively in microservices and SOA, and have since 2015. Before that, I worked principally as a web app developer, and did some work off-and-on in SOA implementations. And before that I spent years becoming oriented to the architecture. I don't make the mistakes that web developers typically do when they presume that web development knowledge is a sufficient prerequisite for working in SOA.

So, it's not a question of whether an architectural style works or doesn't. The majority of failures in microservices can be attributed to ignorance and to the narcissism that is permissive of it.

So, I would ask this question instead: Are there any cases where developer over-confidence and over-simplification went well?

These qualities don't tend to serve any architectural style well.

I've never heard of a well-designed SOA not going well. Every single case of microservice project remediation that I've participated in had as the most significant contributing factor an utter disregard for the body of knowledge that the microservices architectural style is built upon.

There are a lot of things that developers can get away with when doing the kinds of tinkering and wandering that typifies typical web development work. But those things don't work once we cross the line into SOA. And unfortunately, the incessant chasing after trivial resumé candy hasn't prepared the average developer for the rigorous mindset needed for SOA work.

As "microservices" became to next fad for perennial fad chasers of the software development world, they finally encountered a kind of work that they could not get away with by faking it. And so, we see a lot of failures. But the vast majority of the failures are personal failures and character failures, rather than failures of an architectural style.

The fat part of the developer bell curve was simply overreaching when it presumed to try to get away with building service architectures with the same level of disinterest in architecture and process that we can get away with in typical web development. Like a kid with copious experience building kites presuming to strap themselves to a hang glider and just "going for it". The outcomes are mostly predictable.

In the end, if a little time is invested in learning the fundamentals that have so far been eschewed for the sake of expediency, anyone can succeed with SOA and microservices. It's not that the realities of the architectural style are unlearnable, but it can't be arrived at by the level of tinkering and wandering that we can just get away with in monolithic web development.

Re: Why Segment Went Back to a Monolith

#202

Earlier quoted context omitted.

Can you share examples of your data flow diagrams? Do any open source projects share these documents?

Mostly these were white boarded, but essentially I/we would draw a collaboration diagram (although I could have sworn these used to be called something else). They showed what data was needed to make certain decisions (eg, a conditional drop down that is populated based on another piece of data, or complex validation steps) and where to get data that already existed.

activity diagram?

Re: Why Segment Went Back to a Monolith

#203
I see a lot of places that seem to either think that:

1. Microservices will let them ship things faster or

2. It's microservices everywhere or nothing

Microservices might let you ship faster if you are really good at deciding where to draw the lines between services and really good at managing multiple deployment pipelines and all the infra - that's a pretty tough ask.

Also, if you have a monolith it's perfectly fine to pull out one or two parts that need to scale much more efficiently and leave most of your codebase in the monolith, but a lot of times I see companies think once you have created one microservice the monolith is now the worst thing possible and it needs to be broken up entirely.

My general rules for this are to always start in a monolith and break things out as they start to fail or break other parts of the codebase, and don't go all in just because you now have one microservice that works well by itself

Re: Why Segment Went Back to a Monolith

#204
post #19

I think that the problem here was that they were fighting against Conway's Law: https://en.wikipedia.org/wiki/Conway%27s_law > Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure. I think microservices work well in organizations that are big enough to have a team per microservice. However if you've just split your monol…

I cannot agree more: I worked at a company where we went from a monolith deployed on IaaS with a couple handful of engineers to Docker containers deployed on ECS with over 200 engineers. The main reason we did it was because Docker+ECS was cheaper than a bunch of EC2 instances and you can't effectively use 200+ engineers with a single monolith. After 2 years we had over 450 microservices while keeping our AWS bill fl…

On the other hand, over 200 engineers on payroll is way more expensive than a couple handful!

Presumably you're getting significant value out of the additional engineering work in which case the architecture shift probably makes sense (to stay aligned with the expanded organizational structure), but there are also cases where a small and flexible team maintaining a simple monolith would be much more nimble and cost-effective.

Re: Why Segment Went Back to a Monolith

#205

Earlier quoted context omitted.

> split along domain lines with minimum inter-service dependencies. Exactly, and done right that quite often means big 'microservices'. All too often I see the 'functional programming disease' where the aim is to deconstruct to the smallest possible reusable functions ( 'micro' services right? ), often prematurely, creating high levels of compositional complexity and with zero tools to help you understand how the act…

"Yep each single microservice is simple - ..." but the whole is not. I always find it more interesting what's _not_ in the single microservices, the stuff you do see. When you make a diagram with boxes and arrows, the interesting stuff would be the arrows, not the boxes themselves.

Indeed my loudest prescription to people doing service-oriented architectures of any kind is to simplify these arrows.

The common mistakes that I see are for two services to share read access to a common database, or to discover each other and send RPCs to each other. Both really dangerous for exactly this reason! The common database obscures how the two communicate with each other, and invariably everything connected to a database becomes one service -- call it a "mini-lith" if the overlapping sets created by databases do not cover the whole architecture. The problem is the preponderance of implicit arrows; when I reason about what it means to make this datetime nullable so that I can store such-and-so, I need to consider whether everybody who can read that datetime will be prepared for its nullability.

RPCs and APIs are the same way. I add a contract about what I am outputting and then everybody needs to know about my contracts and I must commit to them or else modify all of my consumers. So because the arrows are bi-directional everything just becomes one monolith again.

Instead, I recommend message brokers -- all that pubsub stuff. A given service tells all the other services simultaneously "this happened," and it is their responsibility in their codebase to listen for that event and then say "okay, then this must happen." Publishing a new version of the event is done by just emitting both the old and the new version of the event and perhaps having a shared standard for deprecation across the codebase so that you get deprecation warnings in your prod logs.

Every service has its own database and they generally only communicate to each other through these broadcasts, makes the arrows into the "stuff you do see".

Re: Why Segment Went Back to a Monolith

#206
What's notably absent are descriptions of problems with versioning interfaces, failures from network unreliability, or problems managing connecting infrastructure, or poor delineation of service boundaries leading to undesired change dependencies--which is to say it seems like they executed well. There's no sign they fell into common pitfalls.

There are definitely some good insights here that I don't often read about. The idea that with a sufficient number of microservices (say 50+) you not only treat your instances as-cattle-not-pets you have to treat the service types en-masse as-cattle-not-pets. This requires more automation and organized management as pointed out by the need for tuned autoscaling rules. This requires continued investment into automating things you would do manually if you had 50- services.

The other thing to consider is that going to microservices and back to a monolith is not necessarily a failure. Microservices are good for periods of high change velocity, once a platform is mostly built requiring much less new development consolidation completely makes sense. At all points, we're solving for impedance mismatch, whether that's the org structure, velocity of changes, or numbers of developers vs numbers of deployed units.

Re: Why Segment Went Back to a Monolith

#207
post #31

Earlier quoted context omitted.

As with a lot of things, it comes down to communication. Between teams, and between the services they write. Which is just another expression of Conway's Law. IIRC Fred Brooks pointed out that the # of bugs in a system correlates closely with the # of lines of communication within and between the teams. Joshua Bloch recommends in "Effective Java" that, if possible, 3 potential clients should participate in the design…

> As with a lot of things, it comes down to communication. Between teams, and between the services they write. Which is just another expression of Conway's Law. This is so accurate. I've heard engineers give state not needing to communicate, chillingly, as a positive for microservices, like "we won't need to talk to each other if all of us are working on different services". My other favorite is using microservices a…

I think there's an element of truth to the engineers' claims. Working on different code bases means there are a lot of things you would otherwise need to talk about that now you don't. It's very much the case that you still need your interfaces to be clear (in fact, clearer!) but those discussions can be somewhat isolated, so more work can proceed asynchronously. Just how isolated depends on how exact (and correct) the specifications are, which is a question of trading up-front work against interruption.

Re: Why Segment Went Back to a Monolith

#208
post #170

I'm struggling to understand the problem with shared code and the desire to fragment the code repo! Why can't you have both independently deployed microservices and a shared code base? If the deployment lifecycle is different for each microservices and each deployment is self-contained, then they can be deployed with different versions of the code - even if they use the same source tree and share code. Obviously the…

> Why can't you have both independently deployed microservices and a shared code base? This is what everyone does, so I can't even comprehend what Segment was doing. Maybe they were deploying a fleet of microservices inside a monolithic deployment? If so, there's no wonder it failed.

We do separate code repos, my last place did separate repos, place before that did monolith(s) but still did separate repos for anything not in the same monolith. I'm pretty sure it's more common to do separate repos, rather than mono-repo, for separate services.

Seems to me, though, the problem is people trying so hard to reuse code. That's the main problem cited in the article. People get really gung-ho about reusing code and creating shared libraries, but reusing code is actually bad most of the time. You should strive to only depend on things that you can reasonably expect to not change, and that you don't need to update even if a new version comes out. What you're supposed to do is take that code in the shared library, and make it a microservice, and obey the usual backward/forward compatibility rules.

Using a monolith hides that problem because the code remains easy to update and build, but just as fragile and in need of heavy testing whenever you change code modules that have multiple consumers. That goes against the idea of mono-repos as well.

Re: Why Segment Went Back to a Monolith

#209
post #19

I think that the problem here was that they were fighting against Conway's Law: https://en.wikipedia.org/wiki/Conway%27s_law > Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure. I think microservices work well in organizations that are big enough to have a team per microservice. However if you've just split your monol…

> I think microservices work well in organizations that are big enough to have a team per microservice.

Presumably by definition we’re talking about a few hundred lines of code, or a couple of weeks development time here at most. What does this team do all day otherwise?

Re: Why Segment Went Back to a Monolith

#210

I see quite a few people defending microservices; the org is the problem, they must not have written the software correctly, etc. Most org structures are not great. Most software is not great. If you expect the exception to be the rule you're setting yourself up for a career full of disappointment. Microservices are a modern re-branding of service-oriented architecture, but 'microservices' sounds cuter and less like…

>Cross-team communication, documentation, API publishing and adherence goes from being very low impact within an org to suddenly being critically important.

Totally agree, but I think this is underappreciated by many. People tend to wave this away by just saying we'll just use Swagger/gRPC/whatever-doc-gen-tool, but that's not the main problem. The problem is that each service needs to have some coherent purpose, and must adhere to that purpose. Changes to that must be reflected through a proper API change and migration. But that requires thought, discipline, and (sometimes slow) work.

When you inevitably run into a situation where you could instead throw a quick hack into the wrong service that will make things work now the temptation to do it very strong (bonus points if this is due to regulatory changes). But now you have an undocumented behavior dependency between those services - they're coupled in a subtle way. And eventually the accretion of those results in a distributed monolith instead of a plain-old monolith.

>domain driven design is helpful for splitting into distributed services: split along domain lines with minimum inter-service dependencies

Definitely, yes. But then when your business evolves in some way that causes all your domains to be inappropriate, you're up a creek again. I don't think there's really a solution to that, though.

Post reply on HN