When discussing a 2-3 year architecture roadmap for an eCommerce system that has already been running for a few years, the typical question is—do we need to go microservices?
Microservices are a hot buzzword right now, so it’s natural to consider them for the evolution of the system. However, the primary drivers for re-architecting a monolithic system into microservices are really of business and operational nature, such as:
- Architecting for business growth: As the system serves more customers and processes more transactions, it needs more capacity and resources. But, not all parts of the system may grow at the same speed.
- Handling traffic peaks: Ideally, the system should be able to scale automatically, or at least dynamically in a way that the infrastructure is not pushed to max capacity in order to support peak traffic at all times.
- Faster time to market: There is significant value to the business when adding or modifying a feature takes days or weeks instead of months and doesn’t require excessive (and often expensive) regression testing and a restart of all applications running the entire environment. The answer to this is modularity and designing for replaceability, which is facilitated by microservices.
- Rapid, instant changes to the content and user experience: Many traditional online systems generate the content dynamically at the server side, from the same web application that also contains functionality for checkout, my account and other features (ie. the monolith). This means that while the customer-facing content can be up-to-date, potentially personalized and manageable, constantly regenerating that content consumes vast amount of CPU cycles, creating online dependencies on data storages and potentially other subsystems. The ultimate goal of the microservices architecture is to break this application down into relatively independent services that serve default content, provide information on inventory status, and serve personalized offers and recommendations. These services can then be tuned, scaled and managed to achieve the best user experience.
If requirements are there on the business roadmap, it is feasible to consider architecting the system around microservices, because even with the added complexity, trying to achieve the above-mentioned goals with the monolithic system would just become increasingly difficult and costly.
The idea here is to have a system composed of several self-contained, scalable, replaceable services.
Then the question is, how do we execute on this plan? Rewriting the system from scratch is usually unacceptable. There is an investment into the current platform, the functionality is tested and proven, or there are other functional enhancements that need to be completed in the current system. It may be a better approach to agree on the target architecture and start gradually moving the system towards the target by including the re-architecting activities in the roadmap development plan:
- Identify a change that would address the top priority business concern and plan for the refactoring/migration. For example “decoupling the content management from the transactional parts of the system”, so the changes can be pushed to the site more rapidly.
- When adding a feature (for example ‘You may also like’ or ‘If you spend an additional X…’) instead of blending it into the current app, consider whether it’s something that can provide value as a standalone service that exposes an interface and can be managed independently. It does not need to be running as a standalone process or be deployable on its own at the beginning, but should be well encapsulated with minimum well-understood dependencies.
- When making a significant change to a subsystem—for example MyAccount—consider if this could be the right time to make this an app or service on its own. Again, the important factor is to consider dependencies—on the code as well as the runtime level. If by making a change to the MyAccount service requires that all other modules be recompiled and redeployed, then this is not a good candidate for a migration (yet). But there may be other candidate modules that cover their own specific domain concerns:
- Customer email communication service
- Checkout as a service
- Item availability service
- Commerce search engine
- Various personalization, advisory, or recommendation services
- Product reviews/rating service
As you can see, this picture can quickly start feeling busy, with the number of services growing and adding to the feeling of increased complexity of the solution. To deal with this, the teams need to pay extra attention to the following aspects of the project:
- Architecture clarity: This doesn’t necessarily mean a ‘big design up front’ approach, but the team needs to share a common vision and understanding about which services the system will be composed of, and how the services are going to be built, deployed, and monitored. The team needs to be prepared to adopt different practices (API-first), frameworks (Spring Cloud), common application infrastructure elements—API Gateway, authentication server, service registry, etc. Not all of them are always necessary, but it must be a conscious architectural decision whether they are going to be part of the system or not.
- DevOps: This is another popular buzzword, but extremely important in this context. As the system grows, the number of services can become overwhelming, so in the microservices world, DevOps is a necessary element. That means automation and streamlining of builds, testing deployment, restarts, auto-scaling, alerting, etc. We are not dealing with a single binary file deployed to a few application servers. There could be dozens of smaller pieces of functionality each potentially running in multiple instances, it’s not something that anybody want to support manually. Just imagine manually collecting logs from all these running apps…
There are many ways to get the migration to microservices wrong. By simply following the technology buzz, without a real business case for it, identifying unsuitable services that are too dependent on one another, failing to adopt DevOps practices to address complexity, not developing the right skills within the team etc.
However, with proper planning and risk management, after some time (and stress, and doubts, and panicking of the PM) the team should start feeling some positive impact:
- The system or its important parts scale better
- It’s easier to deliver a new feature without having to restart everything else in the middle of the night
- System components have a clearer purpose, and therefore are simpler to develop, test and replace
The architecture roadmap is the tool that helps to set the direction for the system evolution for 2-3 years into the future. It needs to be well-aligned with the business roadmap, strategic technology and industry direction and with the team skills and capability. Its importance is especially increased with an introduction of new architectural concepts and approaches like microservices.
Interested in what a microservices-based architecture could mean for your business development?