You may have been told, or read, about the amazing advantages and benefits gained by moving away from a monolithic application. What you might not have heard about is how hard it can be and what challenges suddenly arise when you start dividing your application into smaller parts.
Considering that microservices are one of the latest “trends” in web development you have most likely heard the term. You may have also been told, or read, about the amazing advantages and benefits gained by moving away from a single monolithic application into smaller isolated microservices. What you might not have heard about is how hard it can be and what challenges suddenly appear when you start dividing your application into smaller parts.
In this post we’ll discuss some of the benefits and challenges, you might encounter when refactoring your system into a microservice architecture.
The most common method to deal with a spike in traffic to your application is to simply spin up more server instances and “scale up” based on the increased traffic. These
With a monolithic architecture this typically means adding more
Smaller services powering your application means you can scale horizontally and vertically.
For developers, one of the most exciting things about developing software is learning new languages. In a typical monolithic application, while you might have an array of technologies on the front and back end, you are typically “locked in” to the language chosen for the primary architecture of the application. If your backend is powered by PHP, it becomes incredibly difficult to implement a Node.js service into this backend without additional complexity, abstraction, and maintenance.
Using microservices you can pick the best language to use on a per service basis. Since your services should interact with your application in an abstracted way (for instance JSON/XML over REST/RPC in most instances) there is no need for the application to be aware of what is running behind your service.
Another, and possibly more justifiable, benefit of using multiple languages for your services is the use of the “right tool for the job”. Python can be used for natural language processing while Go can be used for high velocity data processing. Since your services have been isolated by business need you can feel free-er to use the appropriate tool for the job.
We should also note: “just because you can, doesn’t mean you should”. Just because you can use a variety of languages on your project does not mean that you actually should. You must also take into consideration the skills and breadth of knowledge of those who might need to work on, or simply debug, your work after you are done.
Splitting your application into smaller services allows you have more granular fault tolerance. We have all seen a web application go down because an underlying service has wiped a database or incorrect code has been deployed. Isolating your services allows you to maintain your application uptime even if you can’t access a portion of it.
We also suggest using discovery services like Kubernetes or Consul to connect to your services. These tools can also be used to restart services that have gone down or redirect your application to a version of the service that is still active.
There are some significant challenges to converting your mission critical application into smaller disparate parts, the least of which is maintaining uptime while you deploy your services.
One of the biggest downsides of moving from a single application package to many is a significant increase in application complexity. You now have to worry about many small applications instead of one.
Documentation will also have to cover the new services as well as integration points. Test plans and code will have to cover both the smaller services as well as a full integration test plan every time you manipulate your services.
Technical debt will also increase significantly and intentional efforts must be made to make sure all team resources understand the smaller services that power your application.
Communicating across services becomes more difficult when your databases are separated. While some great software packages, like gRPC, exist to make inter-service communication possible you still have the same race condition issues and
Transactional processes become very difficult since the databases are specific to the service of groups of services. Transaction definitions must be maintained by the ORM or model service instead of the persistent data storage.
You must now monitor the health of several servers. You can no longer rely on a heartbeat monitor on your web server to make sure your application is still up and running.
I should note this can be accomplished with some service discovery systems like Consul.
All stakeholders and developers must “buy in”. From client to team members, you must make sure that everyone involved believes microservices are the correct way to proceed.
Migration is a very involved process and may delay new feature rollouts. Maintenance may suffer and previously fixed bugs may be re-introduced when migrating your application. Constant regression testing is required.
It requires a complete shift of thinking when it comes to system architecture and many people will not take suggestion that things are no longer “easy” well. Make sure your team mates and stakeholders are aware of the increase cost of debugging after moving.
Moving from a monolithic architecture to a microservice based architecture has many advantages. At a certain scale it will be your best option to continue to deliver the value your customers demand.
Aside from scaling and isolation, microservices are a great way to make your application nimble and your deployments more granular.