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 offers 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.