The objective of this post is to understand micro services , relevant software architecture, design principles and the constraints to be considered while developing micro services.
1. Micro Services
Micro services are small autonomous systems that provide a solution that is unique, distinct within the eco-system. It runs as a full-stack module and collaborates with other micro-services that are part of the eco-system. Sam Newman defines micro services are “Small , Focused and doing one thing very well” in his book “Building Microservices”.
Micro services are created by slicing and dicing a single large monolithic system into many independent autonomous systems. It can also be a plug-gable add-on component to work along with the existing system as a new component or as a green field project.
2. Eco system
Though the concept of micro service is not new, the evolution of cloud technologies, agile methodologies, continuous integration and automatic provisioning (Dev Ops) tools lead to the evolution of micro services.
2.1 Cloud Technologies
One of the important feature of cloud is “Elasticity”. Cloud allows the user to dynamically scale up and scale down the performance and capacity of a system by dynamically increasing or decreasing the infrastructure resources such as virtual machines, storage, data base, etc. If the software is one single large monolithic system, it cannot effectively utilize this capability of the cloud infrastructure, because the inner sub modules and communications pipe across the system could be the bottle neck, which could not scale appropriately.
Since the micro-services are small, independent and full stack systems, it can efficiently use the elastic nature of the cloud infrastructure. By increasing or decreasing the number of instance of a micro-service will directly impact the performance and capacity of the system proportionately.
2.2 Dev Ops
Dev Ops is a methodology focuses on speeding up the process of software development to customer deployment. This methodology concentrates on improving the communication and collaboration between the software development and IT operations by integration, automation and cooperation.
Micro services architecture supports to meet both software engineers and IT professionals objective. Being small, independent component it is relatively easier to develop, test, deploy and recovery (if failure) when compared to large monolithic architectures.
2.3 Agile Methodologies
Agile is the software development process model, which is evolved from Extreme Programming (XP) and Iterative and Incremental (2I) development process models. Agile is best suitable for small teams, working on software deliverable where the requirement volatility is high and time to market is shorter.
As per the agile manifesto, agile prefers :
- Individual interactions over Process and Tools
- Working Software over comprehensive documentation
- Customer Collaboration over contract negotiation
- Responding to Change over following a plan
A small dynamic team which works in agile process model developing a micro service that is small, independent and full-stack application will have a complete product ownership with clear boundaries of responsibility.
3. Design of Micro Services
3.1 Characteristics of Micro Services
Micro services are designed to be small, stateless, in(ter)dependent & full-stack application so that it could be deployed in cloud infrastructure.
Small : Micro services are designed to be small, but defining “small” is subjective. Some of the estimation techniques like lines of code, function points, use cases may be used, but it is not recommended estimation techniques in agile.
In the book Building Microservices the author Sam Newman suggest few techniques to define the size of micro service, they are : It should be small enough to be owned by a small agile development team, re-writable within one or two agile sprints ( typically two to four weeks) or the complexity does not require to refactoring or require further divide into another micro service.
Stateless : A stateless application handles every request with the information contained only within it. Micro services must be stateless and it must service the request without remembering the previous communications from the external system.
In(ter)dependent : Micro services must service the request independently, but it may collaborate with other micro services within the eco-system. For example, a micro service that generates a unique report after interacting with other micro services is an interdependent system. In this scenario, other micro services which only provide the necessary data to reporting micro services may be independent services.
Full-Stack Application : A full stack application is individually deploy-able. It has its own server, network & hosting environment. The business logic, data model and the service interface ( API / UI) must be part of the entire system. Micro service must be a full stack application.
3.2 Architecture Principles
Though SOA is one of the important architecture style helps in designing micro services. There are few more architecture styles and design principles need to be considered while designing micro services. They are:
3.2.1 Single Responsibility Principle (Robert C Martin)
Each micro-service must be responsible for a specific feature or a functionality or aggregation of cohesive functionality. The thump rule to apply this principle is : “Gather those things which change for the same reason, Separate those things which change for the different reason”.
3.2.2 Domain Driven Design
Domain driven design is an architectural principle in-line with object oriented approach. It recommends designing systems to reflect the real world domains. It considers the business domain, elements and behaviors and interactions between business domains. For example, in banking domain, individual micro services can be designed to handle various business functions such as retail banking, on-line banking, on-line trading etc. The retail banking micro-service can offer services related to that eg. open a bank account, cash withdraw, cash deposits, etc.
3.2.3 Service Oriented Architecture
The Service Oriented Architecture (SOA) is an architecture style, which enforces certain principles and philosophies. Following are the principles of SOA to be adhered while designing micro-services for cloud.
The services must encapsulate the internal implementation details, so that the external system utilizes the services need not worry about the internals. Encapsulation reduces the complexity and enhances the flexibility (adaptability to change) of the system .
184.108.40.206 Loose Coupling
The changes in one micro-system should have zero or minimum impact on other services in the eco-system. This principle also suggests having a loosely coupled communication methods between the micro services. As per SOA, RESTful APIs are more suitable than Java RMI, where the later enforces a technology on other micro-services.
220.127.116.11 Separation of Concern
Develop the micro-services based on distinct features with zero overlap with other functions. The main objective is to reduce the interaction between services so that they are highly cohesive and loosely coupled. If we separate the functionality across wrong boundaries will lead tight coupling and increased complexity between services.
The above core principles of SOA provided only a gist of SOA. There are more principles and philosophies of SOA which nicely fits into design principles of micro-services for cloud.
3.2.4 Hexagonal Architecture
This architecture style is proposed by Alistair Cockburn . It allows an application to equally driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases. This also called as “Ports-Adapters Architecture”, where the ports and adapters encapsulate the core application to function unanimously to external requests. The ports and adapters handles the external messages and convert them into appropriate functions or methods exposed by the inner core application. A typical micro service exposes RESTful APIs for external communication, message broker interface (eg. RabbitMQ, HornetQ, etc) for event notification and database adapters for persistence makes hexagonal architecture as a most suitable style for micro service development.
Though there are many architectural styles & principles the above items have high relevant to micro services.
4 Design Constraints
The design constraints (non-functional requirements) are the important decision makers while designing micro services. The success of a system is completely depends on Availability, Scalability, Performance, Usability and Flexibility.
The golden rule for availability says, anticipate failures and design accordingly so that the systems will be available for 99.999% ( Five Nines). It means the system can go down only for a 5.5 minutes for an entire year. The cluster model is used to support high availability, where it suggests having group of services run in Active-Active mode or Active-Standby model.
So while designing micro services, it must be designed for appropriate clustering and high-availability model. The basic properties of micro-services such as stateless, independent & full stack will help us to run multiple instances in parallel in active-active or active-standby mode.
Micro services must be scale-able both horizontally and vertically. Being horizontally scale-able, we can have multiple instances of the micro-service to increase the performance of the system. The design of the micro services must support horizontal scaling ( scale-out).
Also micro-services should be scale-able vertically (scale-in). If a micro-service is hosted in a system with medium configuration such AWS EC2 t2-small (1-core, 2-GB memory) is moved to M4 10x-large ( 40 core & 160GB memory) it should scale accordingly. Similarly downsizing the system capacity must also be possible.
Performance is measured by throughput, response time (eg. 2500 TPS -transactions per second) . The performance requirements must be available in the beginning of the design phase itself. There are technologies and design choices will affect the performance. They are :
- Synchronous or Asynchronous communication
- Blocking or Non-blocking APIs
- RESTful API or RPC
- XML or JSON , choice of
- SQL or NoSQL
- HornetQ or RabbitMQ
- MongoDB or Cassandra or CouchBase
So, appropriate technology and design decisions must be taken, to avoid re-work in the later stage.
Usability aspects of the design focuses on hiding the internal design, architecture, technology and other complexities to the end user or other system. Most of the time, micro services expose APIs to the end user as well as to other micro-services. So, the APIs must be designed in a normalized way, so that it is easy to achieve the required services with minimal number of API calls.
Flexibility measures the adaptability to change. In the micro-services eco-system, where each micro-service is owned by different teams and developed in agile methodology, change will happen faster than any other systems. The micro-services may not inter-operate if they don’t adapt or accommodate the change in other systems. So, there must be a proper mechanism in place to avoid such scenarios, which could include publishing the APIs, documenting the functional changes, clear communication plans.
This briefly summarizes the important design constraints for micro-services.
5. New Problem Spaces
Though there are many positives with micro-services, it can create some new challenges.
5.1 Complete Functional Testing
The end to end functional testing will be a great challenge in micro-services environment, because we might need to deploy many micro-services to validate single business functionality. Each micro-service might have its own way of installation and configuration.
5.2 Data Integrity across the eco-system
Micro systems run independently and asynchronously, they communicate each other through proper protocols or APIs. This could result in data integrity issues momentarily or out-of-sync due to failures. So we might need additional services to monitor the data integrity issues.
5.3 Increased Complexity
The complexity increases many folds, when a single monolithic is split into ten to twenty micro-services and introduction of load balance server, monitoring, logging and auditing servers in to the eco-systems increases the operational overhead. Also the competency needed to manage and deploy the micro-services becomes very critical, where the IT admins and DevOps engineers need to be aware of plethora of technologies used by independent agile development teams.
The articles “Microservices – Not a free lunch !” and Service Disoriented Architecture clearly warns us to be aware of issues with micro services, though they greatly support and favour this architecture style.
Micro services architecture style offers many advantages, as we discussed it is most suitable for cloud infrastructure, speed up the deployment and recovery , minimizes the damages in case of failures. This article consolidates the needed knowledge areas in design, architecture and design constraints for designing micro-services. Thank you.
 Domain Driven Design – Quickly http://www.infoq.com/minibooks/domain-driven-design-quickly
 MSDN Software Architecture – https://msdn.microsoft.com/en-us/library/ee658093.aspx
 Hexagonal Architecture – http://alistair.cockburn.us/Hexagonal+architecture