Microservices for the enterprise: Designing, developing and deploying
February 28, 2022 / Unisys Corporation
Short on time? Explore these key takeaways:
- When designing a microservices architecture, it is important to:
- Decompose the application into business capabilities.
- Build the services with the appropriate tools and techniques.
- Design the architecture to expose the necessary parts of the services.
- Use the appropriate protocols for communication.
- Decentralize the architecture.
- Deploy the services with consumer-driven contracts.
- Tools and frameworks used to implement microservices include REST, Consul, Oracle Helidon and Kubernetes.
- Benefits of microservices include improved flexibility, scalability and maintainability.
- Challenges of microservices can include increased complexity and difficulty in debugging and testing.
- To successfully implement microservices, it is important to have a clear business strategy and well-defined communication protocols.
- It is also important to have the right tools and technologies and a skilled and experienced development team.
Microservices are becoming more common, particularly in cloud-native application development.
It has emerged as a popular architectural pattern because it allows large applications to be built as a suite of small, independent services that communicate with each other over a network. This approach makes designing, developing and deploying complex software systems easier because you can update and modify individual services without affecting the entire system, making it more flexible and scalable than traditional methods.
Microservices can be implemented using a variety of approaches and technologies. These can include domain-driven designs, continuous delivery, scalable platforms, infrastructure automation and usage of different programming languages. Microservices mirror how business leaders want to organize their teams and application development processes.
Getting started with microservices architecture
When designing microservices architecture, there is no definitive set of standard principles. However, there are some design themes and techniques used by various organizations to get started with the initial stages of building an efficient microservices architecture.
First, identifying applications’ business capabilities will help teams build services accordingly. Once the capabilities are identified, the teams can decide which service they want to work on and start building according to their business requirements. Each team can become an expert in the domain they are working on and figure out techniques and strategies that best suit the application.
After identifying the business capabilities, teams can narrow down the required tools, techniques, platforms and approaches for building the services. Approaches such as Java with MySQL and Scala/Spark can be used per the team’s expertise and the application’s requirements.
While designing the microservices architecture, it is imperative to analyze the parts of the services that must be exposed and the protocols that should be used to communicate with the given services. Unnecessary and heavy detailing will lead to confusion and loss of flexibility in the services.
The architecture can be decentralized by teams working on specific services. An internal source model will allow developers to make the necessary changes in the code and move ahead without relying on the service owner to rectify errors. A detailed service model will simplify the process for the developers, resulting in better performance and development.
A detailed consumer-driven contract will assist each consumer API in capturing the application’s requirements. These contracts are shared with the service providers to help them fulfill the needs of each client. It is essential to pass consumer-driven agreements before deploying the services to help providers understand the interdependency of the services.
Some tools and frameworks for implementing microservices
Representational State Transfer (REST) is an efficient tool that allows microservices to communicate directly via HTTP and is used for building RESTful APIs. The requests and responses are handled using standard formats such as XML, HTML and JSON.
A service discovery technology, Consul offers support for HTTP REST APIs and DNS. This framework allows developers to auto-generate configuration in files using a Consul template. It also performs health checks and excludes certain microservices from service discovery when health checks fail.
Helidon is a microservices framework developed and launched by Oracle. It is a repository of Java libraries that developers can use for building microservices architecture. Helidon comes in two variants, Helidon MP and Helidon SE. The former is a viable choice for Java developers as it is an implementation of MicroProfile specifications. The latter acts as a toolkit that supports Java SE features and fluent APIs.
Another Java framework, Spring Boot, offers collaborating components and enables large-scale systems to be built using simple architectures. Spring Boot is easy to integrate with other frameworks due to the inversion of control.
Let’s look at some deployment options:
For the deployment of microservices, developers can choose from these commonly used patterns:
Multiservice instances per host
While using the multiple service instances per host pattern, developers can position one or more physical or virtual hosts to run multiple service instances. Each service functions on a well-known port on one or multiple ports.
There are two variants of this pattern. First, each service instance is a process or a group of processes. Developers can deploy a Java service instance as a web application on an Apache Tomcat server. The other variant involves running multiple service instances in the same process or process group, such as deploying multiple Java web applications on the same Apache Tomcat server or running multiple OSGi bundles in the same container.
The pattern has many benefits, such as efficient use of resources. This efficiency stems from the process or process group running multiple service instances, like multiple web applications sharing the same Apache Tomcat server and JVM.
Service instance per host pattern
This pattern allows developers to run each service in isolation on its personal host. There are two specializations in this approach:
– Service instance per virtual machine
– Service instance per container
Service instance per virtual machine pattern
This approach involves packaging each service as a virtual machine (VM) image, such as an Amazon EC2 AMI. A good example is Netflix, as they have used this approach to deploy their video streaming service by packaging each service as an EC2 AMI using Aminator and deploying each service as an EC2 instance.
Many tools are available to build VMs, such as Aminator, Jenkins and Packer.io. Aminator packages the services as an EC2 AMI, whereas Packer.io automates the VM image creation and supports virtualization technologies like DigitalOcean, VirtualBox, VMware and EC2.
While using the service instance per virtual machine pattern, teams can enjoy the benefits of mature cloud infrastructure and not worry about exhausting resources and CPU memory as the services run in isolation, making the deployment more straightforward and reliable.
Server instance per container pattern
As the name suggests, this pattern involves deploying service instances on their containers. The containers have a dedicated root filesystem and port namespace, which enable teams to limit a container’s memory and CPU resources. Examples of container technologies include Solaris Zones and Docker. Teams might also use Kubernetes and Marathon to manage the container placement aligned with the resources required and resources available on each host.
The benefits of containers are similar to VMs as both approaches involve the isolation of services and allow monitoring of resources consumed by each container. Containers are lightweight and easier to build as no heavy OS boot mechanisms exist.
AWS Lambda is an excellent example of a serverless deployment pattern. The technology supports Node.js, Java and Python services. Teams can package the microservices in a ZIP file and upload it on AWS Lambda to automatically run instances and handle requests.
There are four ways to implement the AWS Lambda function:
- Invoking the function directly by using a web service request
- Implementing automatically in response to events generated by AWS services, including DynamoDB, Kinesis, S3 or Simple Email Service
- Using AWS API Gateway to manage HTTP requests from clients of the application
- Following a cron-like schedule periodically
AWS Lambda is one of the most convenient ways to deploy microservices. It offers the benefit of request-based pricing that allows organizations to pay for the world that the services perform, enabling teams to focus more on developing the application instead of worrying about the IT infrastructure.
Success is a moving target, and when it comes to scaling technology, there’s no silver bullet. Microservices are a relatively new approach, but they show incomparable results when executed correctly. Microservices help break more significant applications into smaller pieces that are easier to manage. The process also allows an organization’s culture to be more open and adaptable to changes and improvements.
Global players, including Coca-Cola, Netflix, Amazon and Etsy, have resolved their most complicated problems related to scaling and expansion using the microservices architecture. This shift has allowed these organizations and others to gain flexibility, durability and enhanced engagement within teams.
With microservices, younger organizations can harness the power of legacy software and modern technologies and simplify the learning curve for teams and the next generation of developers, guiding them toward digital transformation.