Two years ago, Science Warehouse was in a situation typical of other similar technology organisations. Our platform was powered by a large monolithic application, backed by a single logical Oracle database. The application had been developed over a ten-year period and there were legacy issues and some black box problems. The general sense was that something needed to change if we were to continue high-quality development and maintain delivery of high-value features.
Being built in a monolithic way, there were a number of challenges including the following:
- Hidden complexity
- Limited test coverage – both unit and end-to-end
- Lack of build and deployment automation
- The application scaled in big blocks – it ran across 3 large data centre servers. To scale further was not efficient and the application was not designed for standard load-balancing strategies.
- We were restricted to older frameworks, which limited the innovation we could achieve.
We had previously attempted remediation through in-place refactoring and had also considered a full-scale rewrite. However, we were not comfortable with our chances of success with either of those options as the level of risk was high. We needed to do something to improve a situation that was not going to get better on its own!
Microservices – The Solution
We looked at what was happening within the technology industry and decided to investigate Microservices more thoroughly.
We determined the best approach for us was to try an incremental move towards Microservices – we would favour new services over monolith adaption, we would favour immutable services and smaller services and we would utilise standard practices and the new Spring Boot framework.
Others who had made a similar transition to Microservices highlighted six requirements to get Microservices right:
- The ability to balance load
- The ability to failover
- Visibility and early warning of service failure
- Central control of configuration
- The ability to identify the location of services
- The ability to dynamically route requests
In order to enable easy implementation of each service and avoid service creation becoming a bottleneck, we developed a supporting process including automation which provided a set of simple repeatable steps to take a service idea to production in the shortest possible time:
- Consider some design upfront. Create lightweight documentation to answer the architectural considerations for a new service and show the logical layout of the service within the larger system. Make sure to elaborate the service in enough detail to make its place in the system clear.
- Automate any required infrastructure. Standard service templates were provided so a typical set of infrastructure could simply be created efficiently.
- Create the services from standard skeletons. These skeletons, through use of Spring Boot and Spring Cloud, provide the majority of the requirements of a Microservice.
- Automate pipelines for application build and deployment. Standard Jenkins pipelines were provided for Spring Boot applications deploying to Cloud infrastructure. Skeleton applications could be deployed all the way to production, validating a service’s path to production from the start of the development lifecycle.
- Develop business logic. Our standard iterative development could then implement business logic and build features within the service skeleton. With the automation from the previous step, the path to production deployment and live release would be without blockers or last minute stress.
Microservices – What We Have Learned
We have now been developing Microservices for two years and in this time, we have learned a great deal. The original plans and ideas of how to implement Microservices proved to be vital to our success. Some things didn’t go to plan however and we had to adapt and adjust to ensure the Microservice approach was a success.
Our Top Tips
Based on our work with Microservices, what are the main things we have learned?
As well as the previously listed six requirements for Microservices, we have found five additional lessons, from our experience, to consider when implementing Microservices.
- Best practice is vital.
Teams need clear guidelines to enable them to work with Microservices successfully. Without the 12 factors and Cloud native, it is unclear if we would have been able to successfully implement Microservices.
- Cloud was a critical enabler.
The Cloud allowed us to bypass the need for scaling or resilience implementations. It fulfilled a number of Microservice requirements without the need for additional work.
- Log and metric consolidation really help.
Beyond running a couple of Microservices, having visibility into the system becomes a challenge, by consolidating logs and metrics we gained a full system overview. This helps provide early warning of issues and assists with issue resolution.
- Expect a high overhead to controlling system evolution.
In a monolith, complexity is hidden as technical debt; within the Microservice system, complexity becomes quickly apparent and needs to be dealt with to allow the system to continue to evolve.
- An enabling team is a requirement to allow product (feature) teams to maintain focus.
The amount of scaffolding and supporting work required for a Microservice system is high. Placing this burden on feature teams would slow down development too much and likely result in an inconsistent Microservice system. Someone needs to manage the creation of skeletons, the definition of standard solutions and the automation of infrastructure and service deployments. For the most efficient use of feature team time, a platform on which to develop and run Microservices must be provided.
To Microservice or not to Microservice? Would we do it all again?
After two years of work with Microservices was it the right path to take? Has it been a success?
Our pace of development has certainly increased; smaller code bases and bounded contexts have led to more focused development. Through this increased development pace and ease of deployment, our rate of release into production has increased.
In 2017, we carried out over 200 deployments; in previous years, our monolith may have had as few as one deployment a quarter.
We are able to carry out Microservice deployments with zero downtime, any time of the day; this reduces the risk of change and allows features to reach our customers faster.
The system as a whole is now more resilient and better able to scale. Exposed monitoring allows us to see where our system is being used and focus development in the most valuable areas.
Microservices have been the right solution for us and has been highly successful. We look forward to continuing to develop our solutions further, to meet the needs of our current and future clients.
To read more about the solutions we offer, visit our solutions pages.
Contact us if you want to find out more about how our technology is helping organisations to achieve their procurement objectives.