Live data from Hacker News

Don't start with microservices – monoliths are your friend

arnoldgalovics.com

311–320 of 468 posts

Re: Don't start with microservices – monoliths are your friend

#311
post #293

Earlier quoted context omitted.

Monoliths don’t actually look like that at scale. For example you can easily have multiple different data stores for different reasons, including multiple different kinds of databases. Here’s this tiny little internal relational database used internally, and there’s the giant tape library that’s archiving all this scientific data we actually care about. Here’s the hard real time system, and over there’s the billing d…

But all those data sources are connected to from the same runtime, right? And to run it locally you need access to dev versions of all of them. And when there’s a security vulnerability in your comment system your tape library gets wiped.

This actually feels like a good example of the modularity that i talked about and feature flags. Of course, in some projects, it's not what one would call a new architecture (like in my blog post), but rather just careful usage of feature flags.

> But all those data sources are connected to from the same runtime, right?

Surely you could have multiple instances of your monolithic app:

  # Runs internally
  app_instance_1_admin_interface:
    environment:
      FEATURE_ENABLE_ADMIN_INTERFACE=true
  # Runs interally
  app_instance_2_tape_backup_job:
    environment:
      FEATURE_ENABLE_TAPE_BACKUP_JOB=true
  # Exposed externally through LB
  app_instance_3_comment_system:
    environment:
      FEATURE_ENABLE_COMMENT_SYSTEM=true
If the actual code doesn't violate the 12 Factor App principles, there should be no problems with these runtimes working in parallel: https://12factor.net/ (e.g. storing data in memory vs in something external like Redis, or using the file system for storage vs something like S3)

> And to run it locally you need access to dev versions of all of them.

With the above, that's no longer necessary. Even in the more traditional monolithic profiles without explicit feature flags at work, i still have different run profiles.

Do i want to connect to a live data source and work with some of the test data on the shared dev server? I can probably do that. Do i want to just mock the functionality instead and use some customizable data generation logic for testing? Maybe a local database instance that's running in a container so i don't have to deal with the VPN slowness? Or maybe switch between a local service that i have running locally and another one on the dev server, to see whether they differ in any way?

All of that is easily possible nowadays.

> And when there’s a security vulnerability in your comment system your tape library gets wiped.

Unless the code for the comment system isn't loaded, because the functionality isn't enabled.

This last bit is where i think everything falls apart. Too many frameworks out there are okay with "magic" - taking away control over how your code and its dependencies are initialized, oftentimes doing so dynamically with overcomplicated logic (such as DI in the Spring framework in Java), vs the startup of your application's threads being a matter of a long list of features and their corresponding feature flag/configuration checks in your programming language of choice.

Personally, i feel that in that particular regard, we'd benefit more from a lack of reflection, DSLs, configuration in XML/YAML etc., at least when you're trying to replace writing code in your actual programming language with those, as opposed to using any of them as simple key-value stores for your code to process.

Re: Don't start with microservices – monoliths are your friend

#312

Former Netflix engineer and manager here. My advice: Start a greenfield project using what you know (unless your main goal is learning) keeping things as simple as possible. Microservices is more often an organization hack than a scaling hack. Refactor to separate microservices when either: 1) the team is growing and needs to split into multiple teams, or 2) high traffic forces you to scale horizontally. #1 is more l…

> Refactor to separate microservices when either: 1) the team is growing and needs to split into multiple teams

I've heard this before, and I just don't get it. I've worked on multiple monoliths where hundreds of engineers contribute, and it's fine. You have to invest a bit in tooling and recommended patterns to keep things from going crazy, but you kind of need to do that either way.

> At 35-50 people a common limiting factor is coordination between engineers

So don't coordinate? If engineers working on different aspects of the codebase need to coordinate, that feels like something is wrong architecturally.

Re: Don't start with microservices – monoliths are your friend

#313
post #26

Unless you have a strong technical or organizational reason to use microservices, using microservices is just more work to achieve the same results. Organizational reason would be multiple people/teams who don't want or can't talk much to each other, so they develop pieces of a larger system as relatively independent projects, with clear API and responsibility boundaries. Frontend/backend style web development is an…

> no good reason How about deployment speed? If I’ve got a microservice collecting events off a queue and writing a csv out to S3 on a schedule, it’s really nice to be able to add a column and deploy in minutes without having to rebuild and deploy a giant monolith. It also allows for fine grained permissions: that service can only read from that specific queue and write to that specific bucket. People throw around “d…

> it’s really nice to be able to add a column and deploy in minutes without having to rebuild and deploy a giant monolith

This is orthogonal to monolith vs microservices. I've worked on monoliths that could easily be (and were) deployed very frequently.

Re: Don't start with microservices – monoliths are your friend

#314
post #293

Earlier quoted context omitted.

Monoliths don’t actually look like that at scale. For example you can easily have multiple different data stores for different reasons, including multiple different kinds of databases. Here’s this tiny little internal relational database used internally, and there’s the giant tape library that’s archiving all this scientific data we actually care about. Here’s the hard real time system, and over there’s the billing d…

But all those data sources are connected to from the same runtime, right? And to run it locally you need access to dev versions of all of them. And when there’s a security vulnerability in your comment system your tape library gets wiped.

> But all those data sources are connected to from the same runtime, right?

Not always directly, often a modern wrapper is setup around a legacy system that was never designed for network access. This can easily mean two different build systems etc, but people argue about what is and isn’t a monolith at that point.

Nobody counts the database or OS as separate systems in these breakdowns so IMO the terms are somewhat flexible. Plenty of stories go “In the beginning someone built a spreadsheet … shell script … and the great beast was hidden behind a service. Woe be unto thee who dare dare disturb his slumber.”

Re: Don't start with microservices – monoliths are your friend

#315
post #281

Someone please write an article, "Don't start with architecture some dude suggested because of their ego". There are cases when monolith is bad, and when microservice is the must. Take the healthy approach. The article is garbage with no real understanding how real microservices works: The deployment: Modern microservices are working using templates. You deploy it using that directly from you gitlab/github. You copy…

This article sounds like someone who's never successfully implemented either solution. Things that are wrong so far:

Monolithic apps need monitoring (e.g. Prometheus) just as much as microservices.

Monolithic apps can have scaling issues if you only have one database instance (especially if you're write-heavy), so you may need to shard anyway.

Monolithic apps will probably want a messaging system or queue to handle asynchronous tasks (e.g. sending e-mail, exporting data).

Microservices do not require kubernetes. You can run them fine on other systems; at my last job, we just ran uwsgi processes on bare metal.

Microservices do not require a realtime messaging system. You can just use API calls over HTTP, or gRPC, or whatever else. You'll probably want some kind of message queue as above, but not as an integral part of your architecture, meaning it can just be Redis instead of Kafka.

Microservices do not require separate DB instances. If your microservices are all using separate schemas (which they should), you can migrate a service's schema to a new DB primary/replica set whenever you want. In fact, if you have one e.g. MySQL primary you can have multiple secondaries, each only replicating one schema, to handle read load from individual services (e.g. a primary write node and then separate read nodes for user data, product information, and everything else). When it's time to break out the user data into a separate database, just make the read replica the new primary for that DB and add a new read replica off that.

This dude just straight up doesn't know what he's talking about, and it sounds like his experience with microservices is following a bad 'microservices with golang, kafka, cassandra, prometheus, and grafana on k8s' tutorial.

Here's how you write baby's first microservices architecture (in whatever language you use):

1. Decide where the boundaries are in your given application; e.g. user data, product data, frontend rendering, payment systems

2. Write those services separately with HTTP/gRPC/whatever APIs as your interface.

3. For each API, also write a lightweight native interface library, e.g. user_interface, product_interface, payment_interface. Your services use this to call each other, and the method by which they communicate is an implementation detail left up to the interface library itself.

4. Each service gets its own database schema; e.g. user, product, payment, which all live on the same MySQL (or RDS or whatever) instance and read replica.

5. Everything has either its own port or its own hostname, so that your nginx instances can route requests correctly.

There, now you have a working system which behaves like a monolith (working via what seems like internal APIs) but is actually a microservice architecture whose individual components can be scaled, refactored, or rewritten without any changes to the rest of the system. When you swap out your django protobuf-over-HTTP payment processing backend for a Rust process taking gRPC calls over Redis queues, you change your interface file accordingly and literally no one else has to know.

It also means that your deployment times are faster, your unit testing is faster, your CI/CD is faster, and your application startup time is faster when you do have to do a service restart.

I'm not sure why this is so hard for people to understand.

Re: Don't start with microservices – monoliths are your friend

#316

I wonder why no one ever talks about architectures in the middle between those two - modular monoliths. The point in time where you're splitting your codebase up in modules (or maybe are a proponent of hexagonal architecture and have designed it that way from the beginning), leading to being able to put functionality behind feature flags. That way, you can still run it either as a single instance monolith, or a set o…

I even wonder why the word "monolith" got such a bad connotation that it is now used synonymously to "big ball of mud". I mean, monoliths in the original sense (Washington Monument, that 2001 - A Space Odyssee moon thing, ...) are all but messy.

Re: Don't start with microservices – monoliths are your friend

#317

Former Netflix engineer and manager here. My advice: Start a greenfield project using what you know (unless your main goal is learning) keeping things as simple as possible. Microservices is more often an organization hack than a scaling hack. Refactor to separate microservices when either: 1) the team is growing and needs to split into multiple teams, or 2) high traffic forces you to scale horizontally. #1 is more l…

What was the root cause of the dependency horror that Netflix created, now immortalized with all the scary data flow GIFs?

I assume you're referring to the visualizations like the ones halfway down this post? https://netflixtechblog.com/vizceral-open-source-acc0c32113f...

It wasn't really a horror, and those charts are a little misleading. I'll try to explain.

Plenty of others who were also there at the time might see it differently, but IMO this was a trade off to get higher productivity and higher resiliency at the cost of higher complexity. So it was a feature not a bug.

When the cloud migration began in 2010, we had a straightforward architecture of a handful of Java monoliths and a giant Oracle database all running in a local data center. The DVD service made all the revenue but the future was the streaming service. It would turn out over the next 10 years we would need to grow engineering headcount over 10x to support the growing business complexity. Some of that complexity was foreseen and the intent was to address it with a culture analogous to a cellular ecosystem.

There are many successful designs in nature that evolved to a complexity beyond our current understanding, like the human body or even the protein signalling pathways within individual cells. These systems tend to have excellent homeostasis and survivability in the face of novel stimuli. Notably, each cell is fairly independent: it can receive signals but it acts on its own, and its internal complexity can be hidden from its neighbors.

We created a culture where teams were independent units. The sayings were, "loosely coupled and tightly aligned," and, "no red tape to ship." This is the opposite of an architect making top-down decisions. Instead we prioritized local decision making within teams which tends to be fast and effective, so this worked out well for productivity. But the side effect is that the overall system grew a bit beyond the limit of any one person to easily understand it. Thus the automated tooling to visualize the graph. But the dependency graph itself was rarely a problem. Any given developer was usually able to trace all the requests they were responsible for all the way down the dependency graph, and that's what really matters for development and debugging. Generally, no one needed to grok the zoomed out picture -- even during outages, problems were typically root caused to a particular service, and not related to the whole dependency graph.

But the dependency graph makes for a compelling graphic, so it gets people's attention. The real story is, "productive organizational culture made of independent units."

Re: Don't start with microservices – monoliths are your friend

#318
post #9

There is a lot of talk about monoliths vs microservices lately.. I just want to throw into the ring that you can do both at the same time. easily. And noone is going to kill you for it either. maybe we are getting caught up in sematics because its christmas, but "monorepo/monolith/microservices/etc" is -just- the way you organize your code. Developing a montolith for years but now you have written a 15 line golang ht…

> There is a lot of talk about monoliths vs microservices lately.

Actually it's been going on for years, and it's always the same argument. People think they're thought leaders for saying "Start with monoliths and only move to microservices if you absolutely need to!"

It's a pretty obvious conclusion to anyone who has worked in both environments, or have had to migrate from one to the other, so it's not particularly insightful. And yet here were are, 5+ years later saying the same thing over and over again.

Re: Don't start with microservices – monoliths are your friend

#319
> If you’re going with a microservice: A Kubernetes cluster A load balancer Multiple compute instances for running the app and hosting the K8S cluster

Try running a high-traffic high-functionality website without something equivalent to this. What's this magical single computer you'll be running it all on? You'll need a cluster of servers on a rack somewhere, managed the old fashioned way. You'll need equivalent tools to deploy to them and monitor them.

I think what this article should be getting at is that low-traffic sites shouldn't start with microservices, and maybe that's true. But if you're trying to build a business that scales rapidly, you want to be ready to scale your website from day one.

Re: Don't start with microservices – monoliths are your friend

#320

I wonder why no one ever talks about architectures in the middle between those two - modular monoliths. The point in time where you're splitting your codebase up in modules (or maybe are a proponent of hexagonal architecture and have designed it that way from the beginning), leading to being able to put functionality behind feature flags. That way, you can still run it either as a single instance monolith, or a set o…

Maybe because breaking up a monolith has proved to be as hard as combining microservices, once you get past the obvious and trivial steps.
Post reply on HN