Microservices are great. They are also complex, expensive and require much higher expertise.
Start with a well groomed monolith that is well modularized then split it when scale (user scale, team scale) makes sense.
Microservices are great. They are also complex, expensive and require much higher expertise.
Start with a well groomed monolith that is well modularized then split it when scale (user scale, team scale) makes sense.
I would say the complexity is largely in deployment. Otherwise, I find microservices much simpler to reason about.
As an example, keeping a bunch of small, isolated microservices behind queues means that I can reason about them very locally. I know what data they own, I know their interfaces, and I don't really need to think 'outside' fo them - they just send other asynchronous messages out. I don't need to think about dependencies very much - if a downstream or upstream server fails it is irrelevant to the microservices, so long as the queueing system is up.
It's a bit more annoying to get infrastructure and whatnot set up, but not a ton.
> expensive
Maybe? Shouldn't finger grained scaling be cheaper in some cases?
> require much higher expertise
I don't really agree. Again, by keeping things small and by maintaining the ability to reason about components locally, I think that it's easier to work with microservices than monoliths.
> Due to the monolithic software architecture, it was difficult to add new features without affecting the entire system and it was quite complex to release new changes, since we had to rebuild and redeploy the entire product, even though we changed only a few lines of code. That resulted in high risk deployments which happened less frequently - new features got released slowly.
From the article. For a startup the ability to add features quickly is pretty important - especially early on.
I'm not advocating microservices first for every situation, but I've built systems microservice-first and it's been fine.
So we're sending a new data model in the form of JSON over TCP using AMQP? Or are we using STOMP over websockets? Who maintains the broker? Do we use a direct exchange or topic exchange? How do we replicate messages across exchange nodes to ensure uptime? How do we upgrade the broker?
> Shouldn't finger grained scaling be cheaper in some cases?
Monolith, basic high availability is 3 servers, minimum. Now every single microservice needs 3x servers, plus autoscaling, plus we need things like distributed logs, a resilient broker, etc. Even simple things like uptime pinging are more expensive because we're tracking more hosts.
Sure, if you ignore everything outside of your system then it's really easy to work on a single microservice, and if your startup has several million dollars and hundreds of engineers - great, use microservices.
Uh? I don't know? Like, I know how I've done it, idk how you want to do it, and I won't prescribe implementation details as if they're universal.
> Monolith, basic high availability is 3 servers, minimum. Now every single microservice needs 3x servers, plus autoscaling, plus we need things like distributed logs, a resilient broker, etc. Even simple things like uptime pinging are more expensive because we're tracking more hosts.
If you can run your entire project on 3 systems, yeah, sounds like a case where splitting out would be more expensive. Though you can do microservices without having separate hardware - just stick them on the same box. You still get software fault isolation.
> Sure, if you ignore everything outside of your system then it's really easy to work on a single microservice, and if your startup has several million dollars and hundreds of engineers - great, use microservices.
That seems like an exaggeration.
The elephant in the room is the problem domain. If your domain doesn’t decompose cleanly into services then your base maintenance costs skyrocket. I hate these discussions on HN because there’s so much generalization and opinionated arrogance, when in reality the particulars of a given situation matter far more than high level principles or dev ideology.
Well, the post that I was responding to stated the tradeoffs (complexity). And I was responding by saying that 'complexity' is a bit nebulous - and, in my experience, is reduced in some areas (very easy to reason about independent microservices without having to consider dependencies).
> Debugging systemic issues across distributed systems is automatically one or more orders of magnitude more difficult.
Sure, I guess. I haven't really run into issues that good correlation ids + instrumentation can't help with. Also, I find it really easy to target metrics and 'smoke alerts' to small services. Ideally, in a distributed system, you aren't worrying too much about distributed debugging so much as a single service failure.
> I hate these discussions on HN because there’s so much generalization and opinionated arrogance
Whoof. Let's take a step back here. I shared my experience and opinion, I don't think I'm being arrogant by doing so. I stated that microservice-first is not always the way to go, but that it can work - and I pointed to an area in the article that I thought really highlighted this point (the need to build features rapidly).
A counter-argument can be made on this point. You can implement the same isolation levels (modules) but as a monolith using message passing. How is it harder to reason about it then?
In other words, the hard part is how to split your program complexity in modules that are as simple and as orthogonal as possible.
The worse you do this split:
- In a monolithic system, the system becomes exponentially more complex and hard to maintain. You get more bugs, and developers running away from this project as fast as they can, but the thing may fulfill its goals to some degree.
- In a microservice-based system, you may end up either with a handful of huge services (a monolith that uses network-based messages instead of function calls/inproc message passing), or with gross inconsistency problems if you force splits in the wrong places.
Given the operational overhead and that most startups will never get to large scale, I'd say go with the monolith and try to gain traction with your startup. If/when you finally require scale you should have plenty of resources to either split the monolith (if it was well modularized) or just rewrite chunks as services until you get to a fully microservice-based architecture.
Microservice architecture tells you more about how and where to split - introducing bounded contexts and various patterns you might use.
> - In a microservice-based system, you may end up either with a handful of huge services (a monolith that uses network-based messages instead of function calls/inproc message passing), or with gross inconsistency problems if you force splits in the wrong places.
Sure. You can also write really gross, convoluted monoliths.
> Given the operational overhead and that most startups will never get to large scale, I'd say go with the monolith and try to gain traction with your startup.
As the article states, they found that microservices allowed them to move faster on features, which is something that'll matter a lot to a startup. They do, of course, state that there were upfront costs.
The architecture doesn't tell you anything: it is you who decide how to split. Yes, there are guides and what not to help you make this decision, but again you could do exactly the same splits in a monolithic system.
> Sure. You can also write really gross, convoluted monoliths.
Totally. That's what I was implying when I said "complexity grows exponentially and developers want to run away from the project like hell".
> they found that microservices allowed them to move faster on features
While the article is fine, I don't agree with this affirmation at all. They rewrote the entire system (bit by bit) using better engineering principles, better internal organization, and with a lot of experience about their domain that they didn't have before. As I see it, the outcome you see here is not "microservices!", it is just "doing a better job".
I don't really agree. The major difference between SOA and Microservice is the guiding principals, such as the bounded context.
> As I see it, the outcome you see here is not "microservices!", it is just "doing a better job".
Maybe so.
https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...
I don't. Or rather, unlike that of transactional designs used with RDBMs or services deployed into traditional/commercial SOA stacks with distributed transactions, the scope of "reasoning" about microservices is very limited/developer-focused.
But maybe you're using durable queues with exactly-once delivery guarantees, and "idempotent" work requests, which sure is neat if the app is a good fit.
> Maybe? Shouldn't finger grained scaling be cheaper in some cases?
While not OP, I'm assuming they think it's more expensive from a development POV, not (necessarily) operationally.
The important part is to get instructure working well first. Things like request-id propagation and good automation of deployment.
As an afterthought, it may bury you, but if you think about those first, then you'll probably gonna have a good time.
* That service would work well enough on its own as a startup - it's internally complicated but isolated and requires a very simple abstraction (e.g. doing a postcode lookup service).
* As a facade to create a clean interface to something that is not clean (e.g. a nice REST API that talks to a crazy weird industrial control system over a parallel port which only runs on windows).
* The operational requirements of the code are entirely different (e.g. moving data processing from the webserver to a task server and feeding it via a queue).
* As a means of linking components in a large scale system run by a large organization that has multiple teams that often write code in different languages and have real trouble coordinating with one another but are nonetheless overseen by a crazy smart architect.
The latter was basically where Martin Fowler thought microservices worked well, and it probably did, but he kind of forgot that A) the absence of a crazy smart architect is more common than the presence and B) this was a hack which involved a shit ton of extra operational overhead that was only worth it because it solved a gnarly people problem.
When startups of 7 people run more than 3 services I start looking for the microservice kool aid.
Like staticassertion already mentioned, it depends on the real project and problem to solve.
I've pitched a startup which started directly with an microservice like architecture. It was the best possible approach for the given problem.
Yeah, sure, knives are useful and you can always find exceptions for a few 2 years old.
But still. Pretty good rule.