Enterprise interest in microservices is surging, but as with any trend in the technology industry, it is important to keep things in perspective. While microservices is a “thing” today, you cannot optimize just for this particular trend. Unless you are a startup, it is more than likely that you need to support hybrid processes for the conceivable future.
One of the biggest advantages with microservices is that you are not beholden to a single release cycle to make the improvements needed to one or more parts of a system. You do not have to deploy everything together. If you want to improve one piece of your code or fix a typo, you do not have to wait for the next release cycle, as you do with a monolithic application.
However, the microservices approach is not a panacea for all of your software development and delivery challenges. Plenty can go wrong unless you gain a complete understanding of all of the issues. Here are my four recommendations to help you take advantage of microservices without causing big problems downstream.
1. Decompose Your Data Before the Code
With microservices, you look at a monolithic application as a set of different services that address different parts of the problem as a whole. An e-commerce application is a good example of something that can be broken down into microservices. Users need to be able to log in, browse your product catalog, get recommendations, put things in the shopping carts, check out, and have their payment processed.
If you plan on migrating an existing monolithic application to a microservices architecture, you need a good understanding of the system and how all the services interact with each other. You want to avoid making premature or foolish choices about how to decompose your monolith into microservices.
The decisions you make about database schemas—whether you want to provision a separate database for each service, or have private tables per service—and what you do with foreign keys can all have a direct impact on overhead and total cost of ownership.
Here’s my advice: Decompose your data before you decompose your code.
2. Start With a Small Monolith Before You Go Big
If you are starting with a plain sheet of paper and a new application, start with a small monolith. First, figure out what your domain looks like and what kinds of data relationships exist. Are you dealing with transactional data or relational data? The answer will have a big impact on your data structure. Understand where your dependencies are before refactoring the application into microservices.
With microservices, most practitioners need to get better at automating the deployment pipeline, from code check-in to production, and to get a lot better at monitoring that environment. You might look at one service and see a problem that may actually be a symptom of another problem upstream. In such situations, you need to have automated processes for rolling back a problematic service, or for switching between a blue and green deployment.
3. Pay Attention to Inter-Services Communication
Service virtualization and inter-service communication represent other big issues. One of the most important considerations with microservices is to have good, well-defined public APIs so that it’s easy to discover and interact with each microservice. It’s not really about whether your developers use REST, HTTP, or JSON, but more about how they use the protocol to enable robust inter-services communications. Things can get complicated quickly when calls between services are delayed or disrupted because of a poorly designed interface.
Microservices typically tend to be deployed in containers because containers provide isolation, are easy to set up or take down, and run only one process. They also have a smaller footprint than a virtual machine, so there is a relatively significant difference in resource utilization.
But if you have 100 services running in 100 containers, you’ll face consequences from an operational and management standpoint. Deployment becomes more complex, and activities such as monitoring, logging, and remediation become increasingly important.
4. Make Sure You Have the Right Skills
By breaking this all up into separate services, microservices allow you to choose a completely different technology stack for each. You could have Java for one service, a simple Avatar service that serves up static content for another, and Apache for a third. The point is, a microservices approach allows you to choose. You can stand up smaller, independent teams to work on individual services, so you don’t have to worry about managing one very large team. Each team can work on an independent release life cycle and won’t be affected by the distribution.
Running containers and microservices at scale also requires multidisciplinary skills that are currently not available in many organizations. Staffing a team for a monolithic application is very different, both technically and culturally, from staffing one for the microservices world, where familiarity with practices such as DevOps and continuous delivery are critical.
Microservices offer a great architecture, but even if you are mandated to use microservices for all your new apps, you still must deal with your old applications. Large organizations, especially, are not going to employ a single architecture. They can have thousands of applications, some legacy, some mainframe, some written in Java, some in COBOL. The real challenge is how to manage all the product deliveries, how to get code into production, and figuring out what your delivery pipeline will look like.