Cloud native software: Microservices
In a prior post  I described the key characteristics of cloud native applications. The early cloud native applications were developed by the web giants who were building software-as-a-service applications that required massive scale on commodity infrastructure. Over time, these applications have all evolved to a distinct architectural style which is fundamentally different from integrated monolith applications deployed as 3 tier systems.
Cloud native applications are service-oriented. A cloud-native application is composed of multiple services and each service is independently scalable, resilient, and composable. Other than scalability, a key advantage of this architectural style is the ability to provide continuous delivery of software. In most cloud-native applications, granular software components running as services can be upgraded without impacting customers. This avoids having to integrate, regression test, stage, and deploy a large monolith code-base, which can take months. Businesses who get this will be able to innovate faster and beat their competition.
In this post I will talk about the microservices pattern that has become synonymous with cloud-native software.
Software Paradigms, Patterns, and Principles
Throughout the history of software, architecture and design paradigms have provided guidelines on how to package behavior (logic) and state (data) for reusability, scalability, and maintainability of software.
With the imperative programming a sequence of operations executes on a shared state. This style can be very efficient for program execution, but is difficult to scale both during development and execution.
With object-oriented design, objects encapsulate behavior and state and provide a well defined interface that other objects can use. Groups of cooperating objects are packaged in software modules. Several design patterns and principles exist for object oriented design  . An overarching goal of these patterns and principles is that designed modules should be loosely coupled with each other, and highly cohesive within the module.
Software objects and modules exist at design time and do not translate directly into run-time entities. Architectural patterns provide proven best practices for system architectures, including deployment and runtime concerns. Service Orientation is a one such set of architectural patterns. With service orientation, software systems are built as a set of cooperating services. Each service is a run-time entity that exposes a well defined contract or interface and is loosely coupled with other services that form the application.
Microservices is a relatively new term that is used to refer to a set of patterns and principles for developing and operating cloud native software.
Similar to service orientation, microservices applications are composed out of multiple services. The microservices approach is to make each service as minimal as it can possibly be, while still delivering a complete business function i.e. minimal yet complete. How big or small the service actually ends up being is really not the important aspect. The goal is to allow business functions to be developed, tested, and operated in relative isolation from each other.
Deciding what belongs in, or out of, a microservice is a similar craft to applying object-oriented design patterns and principles to a module in a monolith system. The desired balance should be to achieve loose coupling across services, and high cohesion between entities within a service.
Microservices applications are typically built using REST architectural constraints  such as clear role separation, statelessness, and uniform interfaces. Service-to-service messaging uses HTTP or asynchronous messaging protocols.Standardizing on REST, provides the benefit of number of service orientation principles, like composition and contracts, without the need for heavy middleware.
The microservices architecture enables horizontal scalability on a per service level. This model allows for best use of cloud resources and the ability to rapidly scale-up, or scale-down, the precise portions of the system that need to be tuned.
The microservices architectural style allows small autonomous teams to develop and operate individual services. A team can now push incremental changes and fixes to their service independently of other teams. In a microservices application deployment, it is common to have multiple versions of services running in the same environment and service-to-services requests to be controlled using HTTP level routing rules. This allows for DevOps best practices such as canary deployment and dark launches of new features.
Without proper tooling in place, the Microservices style of software introduces several challenges and overhead for debugging, troubleshooting, and operating the system. The web giants who pioneered the microservices architecture have also made significant investments in building and maintaining platforms that help address these issues. The NetflixOSS platform is one such example. 
Adopting microservices also requires a rethink of the organization and roles, for software development, testing, and operations. The microservices approach enables continuous delivery of software, but successful continuous delivery also requires adopting a DevOps mindset where developers and operations are part of the same team and share responsibilities. As Adrian Cockroft explains , the traditional definition of “done” was when the code was released to production. Now, “done” is when the code is retired from production.
The microservices pattern bridges the design principles of object-orientation, the architectural principles of service orientation, and the organizational best practices of DevOps. From this perspective, microservices builds on several decades of software best practices and lessons learnt. This is truly exciting. Now, more than ever, software is changing the world and its great to be a developer as we build the next generation of software.
– Jim Bugwadia
- Chris Richardson has written a great introduction to microservices, and discusses scalability, design patterns and the benefits and drawbacks of microservices .
- James Lewis and Martin Fowler posted a series of blog posts on the topic .
- Adrian Cockroft’s presentation are always excellent and provide valuable insights into Netflix’s journey to microservices and NetflixOSS components useful in building microservices applications .
 Cloud native software: key characteristics, Jim Bugwadia, https://www.nirmata.com/2014/05/cloud-native-software-key-characteristics/
 Design Patterns: Elements of Reusable Object-Oriented Software, Erich Gamma et. al.
 Agile Software Development, Principles, Patterns, and Practices, Robert C. Martin
 REST is not about APIs, Jim Bugwadia, https://www.nirmata.com/2013/10/rest-apis-part-1/
 Netflix OSS, http://netflix.github.io/
 Migrating to Cloud Native with Microservices, Adrian Cockroft
 Microservices: Decomposing Applications for Deployability and Scalability, Chris Richardson, http://www.infoq.com/articles/microservices-intro
 Microservices, James Lewis and Martin Fowler, http://martinfowler.com/articles/microservices.html