Microservices - where and when?
What is it?
Many people have probably seen the terms "services oriented architecture" (SOA) and microservices. If you're curious about the differences between them, there's a free ebook from O'Reilly available.
Today I want to focus on the latter. So - you've heard microservices are awesome and you should consider them in your project.
But how do you know when and where it's a good choice to use them?
Most of the time it'll be overengineering to go with microservices, especially when you're building MVP.
There are, however, few circumstances under which you should at least consider using microservices as your application architecture.
A bit of history
Back in the late 2000's when I started my adventure with building web applications, the most common usage of MVC coding pattern was to use model as mapping objects to database, managing associations and providing validations and callbacks. Then some logic in the views and most of the code in controllers.
Some time later people came to their senses and rethought how it should work (still far from perfection, but better) - a controller should only accept request and pass data to the model, but it resulted in situation when instead of fat controllers and skinny models, we had skinny controllers and fat models - still not the best scenario.
Fast forward - skinny controllers, skinny models, fat services. Services are classes that are reusable in different models (think of notification service that gets parameters from model and based on those parameters sends a proper notification)
But also services tend to grow bigger and bigger. And even if they're not, you may end up having dozens of new services in single app, which is hard to maintain.
Another case - your userbase is growing, you're getting more and more data, more things to calculate, transform and visualize - and technology initialy used for your app doesn't necesserily be the best one to do such jobs.
When to use
It's easy to get tempted and use it everywhere, but it would be overkill and overengineering in lot of cases. However there are few scenarios where is very good idea:
- If you have monolithic application which parts of tend to eat a lot of memory or computing power.
- If you want a higher level of security and data separation.
- If you know from the beginning that different parts of the system will need to be scaled a lot, and in different proportions.
- And last but not least - if you are at point where you need to optimize a lot of various pieces of code and want to use technologies that suit particular job the best.
Pros & cons
Like every decision, switching to microservices oriented architecture has its good and bad sides.
Good things are:
- scalability - you can deploy more instances of only services you need, not an entire monolithic application
- performance - you may use python for crawling pages, golang for high rate operations, elixir for real-time features etc.
- elasticity - you're able to scale app more easily
- security - every part of the system can be separated and has its own database, so your users' data is in few places rather than one
And by bad sides I mean things like:
- monitoring - now you have more things to monitor and log, BUT its also good thing as this makes it easier to find a bug
- deployment - to keep everything consistent the only way is to automate builds using Continuous Integration and Continuous Deployment services (and let's say docker for development mode)
- configuration provisioning and service discovery - if you don't want to keep thinking about adding new instances to some configs (which is ridiculous by the way) you should think of tools like etcd, Zookeeper or Consul that are responsible for service discovery
- communication - you will need to share data between different services, for sure. How would you do that? It depends - you have choices like Apache Thrift, REST API, gRPC, messages brokers like ZeroMQ or RabbitMQ or Apache Kafka. It's hard to choose right, so take some time to do some research on this matter.
It comes with costs - approaching microservices-oriented architecture requires skilled developers as it takes some experience to understand more complex systems, and it could also take more time to launch new features as now a few apps may require changes.
On the other side, changing technologies to those that perform better may slow down rising costs of infrastructure.
Building a team capable of managing microservices in different technologies has some positive side effects:
- people with backgrounds in different technologies may easily share the best solutions with each other
- communication between groups improves as they need to keep things consistent and make some compromises,
- you need to keep API documentation updated (well, you need to actually have documentation - many companies still forget about this)
Microservices-based architecture is not golden solution for every problem you may have, but it’s certainly worth considering using it if you need modular, scalable system. It also helps your team grow and learn from each other, especially when you have polyglotic company.
If you'd like to discuss how microservices may help you and your company, drop me an e-mail