Microservices in moderation is king 👑
We need to go back in time, when monoliths were prevalent and mainstream. What exactly is a monolith in software engineering? How and why are they and problem in modern-day cloud-based solutions, and is the alternative better?
Monoliths
Well, it's when you build your whole service as one huge application when it simply could have been split up into separate services. Let's go over an example to see why monoliths might be an issue.
Reusability & single responsibility
Here is the idea that things should be reusable, like a cloth carrier bag for popping to the shops. You expect that carrier bag to work for years if taken care of properly, and you use that single carrier bag for one reason, which is to carry your shopping.
This idea can easily be applied to software, too. For example, within code, you would write functions, but anything that you call more than once, you'd put into a separate function so it's callable from anywhere that you need to. The same principle applies architecturally. Let's take an example of an online retail platform. You could easily just code up a website with NextJS or springboot and create a login system within those frameworks. They might even come with their own login systems available. Now you want to also create a mobile app for the same platform; however, your login system is now tightly coupled with your website, so you'd need your app to talk to your website just to log in.
To avoid this mess, you'd have a login system that's completely decoupled from every other service, the same way as you'd take code out of a function and put it into its own. By having the login system as its own thing, you can create as many UIs as you'd like, and they will all work with the same login platform. You could even use existing solutions like AWS Cognito user pools.
This also means that you can create dedicated services that specialise in specific things, following the single responsibility principle architecturally.
Adding onto reusability, if you build a login system that's containerised, you are able to use this same login platform on any other project you create, reducing build time to your first MVP (Minimum viable product).
Containerisation
Containerisation is the idea that you can package your code into a box with its dependencies. It's like getting a flat pack table which comes with a screwdriver and screws. The table is your app, and the screws are dependencies like Python or Java to actually run said app.
Why even bother putting your app in a container? Have you ever run an app, but it complains you're missing something, an old game requiring DirectX or ordering that table online with screws missing? It's a complete pain. This is the first and most basic advantage of using containerisation. Everything required to run the app is prepackaged.
Since everything required to run the app is part of the container, containers are able to run on anything with a containerization service installed, like Docker or Podman, ranging from the latest desktop PCs to laptops from 20 years ago.
Replication
Going over this quickly, with containers, you're able to replicate a container quickly when needed. Say the online retail platform has a large number of users logging in for black friday sales. If the login system is decoupled from the main app and its containerised, you can scale up and down the capacity that the login service can handle. This is analogous to the prepackaged tables, but this time the vendor can ship the same table to 100 people since each table is the same. This only works if idempotency is maintained.
Separation
With microservices, each service is loosely coupled with the others and is usually containerised too. This means each service can independently be built and updated by completely different teams. It also means each service can run any language and any framework, so long as they have a clear way to communicate with each other, like a properly documented API.
When microservices become an issue
Microservices are great; it's an architecture made for the cloud and allows decoupling of services. However, with anything good, taking it too far will lead to issues.
Yes, decoupling services from a monolith is usually a good idea; however, decoupling things that aren't used much will just introduce other issues, like creating nanoservices. Each of those small, unnecessary microservices might need a separate team to maintain it, and they definitely need their own CI/CD pipelines too. Now each of those services will need to make network calls instead of function calls, which adds to the overall network. It's as if you need to go to different shops for each item on a recipe list, and everyone needs to do the same. There will be tonnes of traffic jams, making it impossible to get anywhere.
You'd now also have to maintain data consistency between the services, such as between product management and inventory. You'd need to make sure the same change propagates to both services. However, with microservices, you'd have to devise your own plan on that to get eventually consistent databases.
Finally, you can also build a microservices app to become a monolith with network calls by having these separated services, but making service A be heavily dependent on a specific version of service B. This breaks the microservices ideology and loses the benefit of having independent releases.
Comments ()