7

Microservices Aren’t Always the Answer: a Case for Monoliths

 2 years ago
source link: https://blog.bitsrc.io/when-microservices-are-not-the-answer-a-case-for-monoliths-895ccefa2728
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Microservices Aren’t Always the Answer: a Case for Monoliths

Sometimes a good monolith is all you need

I know you’re here to virtually kick me in the teeth after reading the title, but hear me out for a second.

In our industry we have these concepts of “best practices”, “ideal architectures”, “best programming languages”, but these are all absolute statements that are never true in real life. There is no “best practice” or “perfect programming language”, not if you don’t take into account your implementation context.

Defining your context with questions such as the ones below can help you define what is a “best practice” or an “ideal architecture”:

  • What are you trying to implement?
  • What kind of team do you have?
  • What tech stack are you more comfortable with?
  • What’s your timeline look like?
  • Are you doing this for a few users or millions?

So let’s take a look at why the monolithic architecture is not only not dead but is also a viable approach.

What is a monolithic architecture?

Let’s make sure we’re all on the same page here.

A monolithic architecture is when you structure your application as a single project thus having to deploy it as a single entity. Usually this means you have your UI code on the same project as your business logic which is also part of the project where your data access code resides.

Essentially, it’s all living together, usually coupled to the point where you can’t really begin to think of deploying a single section of it without having to deploy the entire thing.

If you’re working with JAVA, that would be having to deploy the entire application as a single JAR/WAR file. If you’re a Node.js dev, that would mean having a single folder structure with everything inside it. And so on, you get the point.

This is opposed to what a microservices-based architecture would be, where you structure your project into multiple projects, each one in charge of a section of the whole. I’ve written extensively about microservices, so if you’d like to know more, check out these articles:

But now that we know what a monolith is, why would we want to use it?

What are the advantages of monolithic architectures?

Yes, like with everything in our industry, there are certain advantages that detractors from this pattern tend to ignore.

Testing and debugging a monolithic application is a lot easier.

While this is not true for unit tests, because after all they don’t care about the rest of the application, performing a more holistic type of testing requires a lot less effort when you’re dealing with a monolith. Why is that? Because you only have a single block of code to run and test. With microservices you’d have to start a, potentially, very complex architecture to get them to interact with each other whilst with a monolith everything works within a single execution context. Understanding how different sections of your app connect and interact with each other is a lot easier this way. And the same goes for debugging, imagine having to understand what is the root cause of a problem inside an architecture that sends data through tens of services? You’d have to debug each one individually until you find the culprit, while with a monolith all you have to do is debug once.

Dealing with cross-cutting concerns is simpler.

Activities such as logging, monitoring the performance, or even caching can be quite complicated to orchestrate and can turn into a problem on their own when dealing with microservices. This is because you have multiple applications doing the same thing in different places independently of each other. This is not a problem with monoliths, since everything happens in the same place.

They’re easier to deploy.

Have you ever had to deploy a 10-microservices architecture? The orchestration required can topple the best of the DevOps, especially if you’re having to set it all up manually. And don’t get me started if there are even more services around. Whereas with a monolith, you have to just deploy a single project once and it works.

Scaling it is not that complicated.

The best way to scale a monolith, is to deploy parallel copies and have a load balancer distribute the traffic amongst copies. Granted, you’ll probably want to use something like “sticky sessions” to keep the users interacting with the same copy of the app, unless you’re able to store the session somewhere else.

Coding it can be easier as well.

Writing the code for a monolith can be simpler if it’s not too big. Why is that? Because small projects might benefit from having some minor coupling between different components simplifying your data transfer activities and other interactions. What’s easier? To call a method of a class or to send an HTTP request, serializing the complex object you’re dealing with in memory, and then waiting for a response to then turn it back into a complex object? Sometimes, a simple method call is all you need.

And probably the best benefit that a monolith approach has is that it just works.

1*SlCmVmEsYpys2dADK_y95w.jpeg?q=20
when-microservices-are-not-the-answer-a-case-for-monoliths-895ccefa2728

Sometimes you don’t need fancy, scalable, and highly available services to solve your problems. Sometimes all you need is for it to work, and monoliths are the fastest way to get there. They get the job done, even if they’re not the “cleanest” or more scalable ways of doing that job.

When would you go with a Monolith over Microservices?

This is not an easy question to answer, considering again that your context plays a huge role in it.

However, here are a few general guidelines you can use.

How many users will interact with your application?

Don’t be shy, shoot for the moon, but be somewhat realistic here. In your wildest dreams, are you building this for millions of users? Or are you creating an intranet application that all 10 of your colleagues will interact with? If your answer is more like the second option, then a monolith will do just fine.

How much time do you have in your hands to deal with orchestration and other concerns that are not writing code?

Can you properly make a plan and do you have time to execute it without someone breathing down your neck? If your answer is “no”, then consider how a monolith can potentially reduce development times by avoiding extra problems that are related to microservices-based architectures (such as orchestration, deployment automation, planning the architecture and modularizing the code to avoid duplication, etc).

Are you working on the final product or are you building a PoC to make sure your idea is viable?

Building microservices requires more planning and potentially more effort, and if you’re just building throw-away code (such as a quick PoC) then a monolith might be a simpler approach. That way you can focus on the part of your logic that you’re trying to prove instead of having to solve intrinsic problems related to the architecture.

Do you have an experienced team working on this?

This is a tough one, because I tend to ask developers to learn something when they don’t know or have never done it before. However, if you have a team filled with inexperienced devs (such as not having experience with APIs, or even performing simple HTTP requests) and you’re pressed on time, having them all learn at the same time can be the perfect recipe for disaster. It’s a combination of factors, but if you’re in such a situation, you might want to consider a monolithic approach right now, and ask them to slowly ramp up on microservices-related topics for a future refactor.

Sadly, there is no rule of thumb for picking one architectural approach over the other, it’s gonna have to be a combination of time, team, effort and probably money as well. Keep that in mind and try to make the best decision possible with the information you have.

The key to making a good decision is never to blindly follow trends. Instead, to inform yourself of the pros and cons of every option and then to decide to put those results against your current context. It’s a lot harder, but it also gives you the best results.

So no, monoliths aren’t dead, nor should they be, there are still use cases for them. You should not be considered a bad architect or software developer for suggesting a monolithic approach if you have good reasons for it (heck, you can be a terrible architect for suggesting microservices if you don’t know why you’re saying it).

What do you think? Are you OK with monoliths in the year 2022 or were you disgusted by the whole article? Leave your impressions in the comments!

Build Micro Frontends with components

Just like Microservices, Microfrontends are a great way to speed-up and scale app development, with independent deployments, decoupled codebases, and autonomous teams.

OSS Tools like Bit offer a great developer experience for building component-driven Micro frontends. Build components, collaborate, and compose applications that scale. Give it a try →

0*OkRsNKl4sPWwHmWg?q=20
when-microservices-are-not-the-answer-a-case-for-monoliths-895ccefa2728
An independent product component: watch the auto-generated dependency graph

Still curious to hear about the other side? Check out this piece I wrote about breaking down monoliths.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK