When you first hear about microservices architecture it sounds daunting. What is microservices architecture? How does it work within our software development process? If I do decide to go this route, how do I even begin? Is it the right fit for my organization, solution, or product? Won’t it take a massive amount of development effort to build all these individual services? Rest assured, once you and your organization are familiar with microservices, you can leverage existing frameworks to stand one up in less than an hour.
This blog post is going to get a little technical. For a basic microservices primer, read our previous blog posts Deriving Business Value from a Microservices Architecture and A Recap of the Ascendle Microsoft Microservices Architecture Seminar.
What Exactly Are Microservices?
“The microservices architectural style describes an approach to structuring systems as a collection of loosely-coupled services. The architectural style goes hand-in-hand with small, autonomous teams that develop, deploy, and scale their services independently.” –Atlassian
Achieving Your Business Goals
Microservices have become very popular as they solve a variety of problems to help achieve both business and software development goals. In my previous blog Deriving Business Value from a Microservices Architecture, I discussed considerations to provide business value.
Here are four business needs a microservices architecture can help you with:
- Agility – Your company needs to provide value to your customers at a faster pace. You need the ability to be flexible with changing customer needs.
- Performance – You can increase your applications’ performance by automatically scaling targeted services.
- Resource Planning/Costs – You would benefit from dividing teams’ work along domain boundaries.
- Availability – You can reduce downtime by releasing microservices independently and only release those that have changed. You no longer have to take the system offline to implement new functionality.
Achieving these goals requires implementing a microservices architecture using an iterative approach.
Let’s Get Started With a Monolith
A monolith is a single-tiered application with all code running on a single platform. The user interface and data access layer are coupled together. Starting with a monolith is the best way for a company to get started with microservices. It may seem counterintuitive to start with the architecture you are trying to move away from but remember as humans we first need to learn to crawl, then walk before we are ready to run. We have found the best approach to using microservices architecture requires the same approach.
For new projects, requirements are going to rapidly change as the Minimum Viable Product is being built. The key at this stage is to focus on understanding the domain boundaries, so you’re not designing microservices that need to be redesigned or thrown away. For existing projects, keep that monolith and start by deploying it as a microservice. Don’t worry that you haven’t achieved a true microservices architecture yet. This exercise will get you on the way to learning the differences in deployment and some of the new technologies required for a microservices architecture.
Whichever stage your project is in, you have plenty to learn before you’re ready to develop the final microservices architecture that your application will evolve into.
There are many things to learn and master, which makes diving right into a complete microservices architecture a challenge:
- How to build a microservice
- What a container is and the available tool choices
- How to deploy a microservice
- How to properly size a microservice
- How microservice scaling works
- What orchestration is and what options are available
- How to communicate between services and avoid too much daisy chaining
- How to handle cross-cutting concerns such as logging and security
- How to test microservices
- How to troubleshoot
This list can seem intimidating if you are not experienced with developing microservices, but crawling and then walking through the beginning phases of developing a microservice will lead you to answers for each of these questions.
Docker, Containers and Images… Oh My
Starting with a monolith allows you to focus on learning one thing at a time and prevents you from delaying your progress into the use of microservices architecture.
As you read through the steps for building a microservice, keep these common terms in mind:
Containers are lightweight and portable encapsulations of an environment in which to run applications. They are simple to create, modify and deploy. Microservices are deployed and run in containers.
Images are templates for containers. They contain system libraries, tools and other files and dependencies for the executable code. By taking an image and then adding a few things, including a file system, some settings such as network ports, container name, ID and resource limits, you can create a container.
Docker is a tool designed to make it easier to create, deploy and run applications by using containers. Docker has become an extremely popular way to configure, save, and share common environments in a flexible way. Container orchestration systems such as Kubernetes work with container tools like Docker. Kubernetes is used for automating application deployment, scaling, and management.
Starting with a simple application, deploying it, and verifying everything works allows you to focus on learning. You won’t be distracted by how your application would need to be redesigned. By completing a little bit of everything, you’ll gain more confidence as you deploy a microservice to production. Start with a Docker-enabled “Hello World” application and learn how to deploy using your CI/CD tool.
This example uses Azure and Azure DevOps, though the steps would be similar in another cloud environment.
The general steps for a .NET Core app are:
- Create an empty code repository in Git
- Add code from this project https://github.com/MicrosoftDocs/pipelines-dotnet-core-docker
- Set up a CI Pipeline for building an image and pushing it to a container registry
- Create an Azure Web App for Containers, Linux OS, Configure your Azure Container Registry
- Commit and push your code to Git from step 2
- The commit will trigger continuous integration to build (and run unit tests)
- Continuous Deployment will publish to Azure
For more details see Deploy to an Azure Web App for Containers
Get Your Monolith Running in a Container
For technical details about getting your monolith running in a container, see Containerize a .NET Core app.
The general steps covered in the article are:
- Build an image of your application
- Create a container based on your image
- Start your container
- Attach to the container to verify your application is running
Document any steps that may differ from the article so your teams can use them in the future. Before moving on to creating your first well-designed microservice, research how cross-cutting concerns such as logging and authorization are implemented in a microservices architecture.
Once you’ve gotten to this point, you have learned how to deploy a docker enabled app. You have also learned a way to repackage your monolith so it can run in a container. Now that the mechanics of a microservices architecture have been figured out, you can confidently move forward.
Evolve Your Microservices Architecture
Having figured out how microservices are packaged, deployed, run, and monitored, you can begin to incrementally refactor your monolithic application.
Start by taking on the newest functionality at the top of your product backlog. Refactor the monolith along domain boundaries for the new functionality. It’s much easier to refactor within the same codebase prior to separating out functionality into microservices.
When the domain boundary for the new functionality is clear, you are ready to start creating your first clean microservice. Peel this functionality out of the monolith and into its own container. Take into consideration how this new microservice can be turned into a template containing cross-cutting concerns such as logging and authorization. Once you’re comfortable with communication between the monolith and the microservice and you are ready to create another microservice, it’s time to investigate orchestration.
As with any new technology or architecture, there is a learning curve to get to the point where you are maximizing productivity and in turn producing business results. By starting with a monolith, you incur less risk and maintain the ability to support your existing product. The odds of success are much greater if you’re not attempting to “rewrite the whole thing.” Have the future in mind but start small. Implementing a microservices architecture with an iterative approach will help you achieve your software development goals.
If you are considering moving a monolithic application to a microservices architecture, contact us to schedule an introductory meeting so we can discuss your business goals.