Monoliths – the type of application where all its code is in one single codebase – are extremely common. Just about every application begins as a monolith, in some way or another.
However, there is a major problem with monoliths: they make users depend on code that they aren’t using. When everything is interconnected and interdependent, a single code change or a single new feature breaking can take down the entire structure.
This is a problem for user experience: if one feature isn’t working properly, the user doesn’t want everything to break. The user doesn’t want to be prevented from placing an order because the recommended products section isn’t working. (In this example, this is also a business problem.) It’s also a backend problem: the network administrators have a more difficult time tracing problems if one buggy feature causes a cascading failure, and it becomes more difficult and time-consuming to come back from that failure.
The idea behind microservices is to fix this problem by breaking up an application into manageable pieces. These pieces are interconnected, but they don’t all fail together.
Feature Flags and Microservices
The point of migrating from monolith to microservices is to mitigate risk, but many releases of microservices are very risky. They try to do a parallel upgrade, where they spend a ton of time building out the microservices and then replace the old code and rollout the new code all at once. It’s almost always a mess. But how can you mitigate the risk of migrating?
Enter feature flags.
A feature flag, also called a feature toggle, is a piece of conditional code that separates deployment from release, enables continuous delivery and canary releasing, and has a host of other use cases. It allows you to turn a feature on or off without needing to deploy any additional code. By doing this, feature flags – especially when used as a part of a feature flag service – help to mitigate deployment risk.
This is how you can use feature flagging to migrate to microservices:
- Find an “edge” functionality to begin your microservice migration. This is the opposite of a core functionality; for example, an edge functionality for an ecommerce website would be sending coupon emails to its users.
- Build a microservice version of this functionality. This should not be a complicated process: microservices are, and should be, simple.
- Wrap a feature flag around the code that controls the edge functionality in the original monolith. Set it so that, while it’s off, the monolith code will be run, but when it’s turned on, the microservice code will be run instead.
- Deploy (but don’t release) the things you made in steps 2 and 3 to the production environment. Keep the feature flag turned off; this step is to simply ensure everything still works.
- Using the feature flag management system attached to your feature flag, turn the flag on for a small group of users. (These can be random users, or any set of specific users, such as a group that may have signed up to beta test new releases.)
- If everything goes well with this initial group, turn the flag on for more and more users. Continue to increase the amount of traffic coming to the microservice and make sure it keeps working properly. If at any point it stops working, a rollback is as easy as turning off the feature flag.
- When the microservice is handling all production traffic, make sure to eliminate technical debt by removing the feature flag, and the old monolith code, from the codebase.
This process, creating new microservices one at a time using feature flags, ensures a low-risk release that will be easy on your software development team, easy on your network administrators, and easy on your end users. The feature flags provide you with a kill switch that you can flip at any time, and your feature flag management system should let you track performance of your features and send you near-real-time warnings if something goes wrong. In all, feature flags make it easy to take advantage of microservices.