Microservices could have won the buzzword of the year for 2014. There were countless presentations, conference talks and articles on the Web regarding the subject. However, few organizations use microservices, many people talk about it, but a general FUD remains that clouds how people perceive, and thus adopt, the technology.
Companies like Nike, Netflix and Twitter pioneered microservices adoption. Last year, during the AWS re:Invent conference, Nike’s story was widely shared and referenced as an example of a potential disruptive technology to the enterprise.
Despite that, adopters have been stating out loud: Using microservices is not instant nirvana from the problems of monolithic applications. However, adoption of microservices does improve the efficiency of an organization over time, to allow faster delivery and reaction than previously possible.
Microservices requires discipline, new toolsets and a change in team dynamics that envelopes all aspects of an organization. Some references to explore include Martin Fowler on Microservices, Fred George’s Slideshare and “Building Microservices” by Sam Newman.
I would like to go through four essential checklists which have helped me navigate this technology trend, and which give useful guidance when considering possible adoption of microservices. There are some common symptoms related to monolithic applications which could trigger adoption of microservices, and I call them the “Essential Monolithic Hate List.” Check to see if you can locate some of them in your project:
Checklist #1: Essential Monolithic Hate List
- The team cringes about a decision regarding a certain technology (which is now causing most of the problems in the application.) If a change of technology happens at this stage, it may result in more regression time and impact the business; therefore, the change of technology is avoided.
- The team waits for deployment of a large unit when doing continuous integration and change rollouts. This delays feedback and causes delay in moving ahead with the plans.
- Evolutionary design changes are postponed in favor of feature rollouts, as changes to design require more coordination with architects and product managers.
- It takes a long time for a new team to ramp up and start contributing to an existing codebase. This slows team rotation and induces strong dependency on pre-existing team members.
- When rolling out a change, multiple teams have to be brought together to ensure the change does not break systems upstream or downstream. This leads to many meetings, prolonged decisions and ultimately delay in delivering business value.
- A failure in one part of the system leads to degradation of the entire application, leading to downtime. These failures are hard to identify and difficult to isolate. This produces a full system decline, instead of a partially available system, as failures cannot be contained to one feature or aspect of the system.
- An application deployed on a cloud platform, when handling a cloud instance failure, produces higher operational costs and system design complexities. This leads to a general lack of confidence in cloud platforms, and eventual disagreement among the technical team when considering the application for cloud deployment.
To deal with these symptoms, we need a more modular system that is loosely coupled, and can be changed or maintained in parts, to prevent downtime during failures. Microservices offers a way towards this, and based on numerous accounts of successful adoption stories, a few common patterns have emerged. I call them “Essential Microservices must-haves.”
Checklist #2: Essential Microservices Must-Haves
- It’s better to start with few number of coarse-grained but self-contained services. Fine-graining can happen as the implementation matures over time.
- Microservices introduces a lot of moving parts that were previously non-existent in a monolithic system. The initial Capex will thus be relatively higher as compared to a monolithic application.
- To the developer, operations, and testing fraternity who have extensive experience in monolithics, a microservices-based system is a new reality; hence, they need time to cope with this new shift. It’s important not to rush this — give ample time for the team to ramp up.
- Service composition could be based on multiple factors: self-contained business features that have little shared functionalities, technology used or integration endpoints that are needed to work with.
- Mandatory toolsets that need to be added to the stack: granular monitoring, log aggregation and dashboard, application metrics, automated deployment and system dashboard.
- A gradual change in the team structure and dynamics would be required, necessitating more ownership and cross-functional skills in the team. No more developers, QA people, operations silos…
- There would be a need for standardized service templates that provide boilerplates for development. This will reduce development chatter and the initial ramp up time for development teams. Moreover, it would introduce standardization for the ops team.
- Don’t discard the monolithic application immediately. Instead, have it co-exist with the new microservices, and iteratively deprecate similar functionalities in the monolithic application.
The above checklist clearly indicates the bottom-line for microservices adoption. It’s not easy, and requires a significant investment in people and processes to get started. As with any technology, it’s always better to avoid the big-bang approach, and identify ways to get your toes wet before diving in head first.
I have identified a checklist of some quick wins which would allow an organization to get started, while steering clear of the big-bang approach. I call this the “Essential Microservices Starters.”
Checklist #3: Essential Microservices Starters
- Identify new features that have to be added to the monolithic application, and develop them instead as microservices. Alternatively, if new features cannot be identified, it is desirable to replace features in the monolithic application that are “less-critical” and more “self-contained.”
- Agree on a standard interface for communication between the monolithic application and the new microservice.
- The new microservices needs to be self-contained, and hence, has to have its own runtime environment. The service also needs to be deployed on a separate infrastructure that is isolated, either physically or logically, from the monolithic application.
- Assign a custodian team that is in charge of the development, maintenance and operation of microservices that is separate from the team managing the monolithic application. This custodian team must be cross-functional, and must have full ownership of these services.
- If existing functionality in monoliths is replaced with the new microservices, then the monoliths must be changed to accommodate feature toggling. It may be necessary to have multiple versions of a same feature co-exist in the old monolithic version of feature and the new microservice. The feature toggling will allow switching between use of the new service and the existing code inside the monolithic application. This is useful as you may want to have a fallback, and arrange for a graceful handover of load to the new service.
- Create a service boilerplate as a template to develop and deploy the new service. This service boilerplate should encapsulate the common ingredients that are needed to support the microservices-based system: monitoring, log collection, metrics and safety mechanisms (like timeout, circuit breakers). This service boilerplate must account for polyglot technologies including application servers, database, programming language, etc…
- Agree on building coarse-grained services which are more actively or frequently used, rather than a bunch of fine-grained services. The coarse grained services will lead to fewer network calls being made between the monolithic application and the microservices. Generally, service size selection is a matter of selecting the appropriate trade-offs in a system when deciding on the granularity.
These ideas will allow a safe way to experiment with microservices and augment existing monolithic applications. One other idea is to have a strong mandate in the initial weeks of the adoption to have all non-critical services based on microservices architecture. The idea is to give time to this new paradigm to settle inside the organization, and have teams be able to cope with the challenges of running a hybrid model. As the teams mature using these services, critical functionalities could be taken up by being built purely as microservices.
No technology adoption is without its hiccups, and the same applies to microservices. This is more pronounced when dealing with migrating a monolithic application to a microservices-based architecture. I have captured some of these hiccups in my list of “Essential Microservices Gotchas:”
Checklist #4: Essential Microservices Gotchas
- Service sprawls that require appropriate bookkeeping of the various active services and their specific versions
- Dealing with dead or expired services and endpoints that are no longer used, and using that information to retire the appropriate services
- Performing integration testing after making a change in a particular microservice
- DevOps activity becoming mainstream in the team which has traditionally been anti-DevOps
- Identifying the right size of service – neither too big nor too small
- Investing in either rewriting services or partitioning existing services
Most of the above hiccups are largely the fault of the traditional monolithic thinking for software development. There are tools and practices available that could handle most of the gotchas and create a sustainable environment for development.
The above Essential Checklists are a good place to begin introspection of where you stand, as you choose to begin experimenting with phases of microservices. Like all technology trends at their birth, microservices is in the early stage of mass adoption and, with the growing amounts of literature surrounding it, it will soon become commonplace in enterprise IT.
Vivek Juneja, an engineer based in Seoul, is focused on cloud services and microservices. He started working with cloud platforms in 2008, and was an early adopter of AWS and Eucalyptus. He’s also a technology evangelist and speaks at various technology conferences in India. He wrote @ www.cloudgeek.in and www.vivekjuneja.in, and loves grooming technology communities. You can also reach him by email: firstname.lastname@example.org.
Featured image via Flickr Creative Commons.