Introduction to Microservices
For as long as people have been writing software routines, there has been a desire to manage the resulting product by keeping it simple and separating functions into sub routines/components. Over time several software abstraction models have been used and discarded. What has survived, however, are the battle tested approaches to form classes and interfaces with shared libraries, technology layers using tiers to partition back-end data storage from middle tier business logic and a presentation front-end.
What has not changed over the years are business needs:
- To create services and operate them with scale, efficiency and flexibility.
- Deliver new features quickly to capture market share early and respond to customer demands in an agile way
- Effectively utilize resources and drive cost down over time
Despite the fact that the state-of-the-art for software develop patterns and practices continue to evolve over time; these business drivers remain front and center in the creation of the modern application architecture.
If you ask any software developer that supports a legacy application you will hear about the painful challenges associated with updating a “monolithic” application.
The dangers and pain from Point-to-Point interface approach
One of the biggest problems faced supporting legacy software are Point-to-Point interfaces. Using Point-to-Point interfaces were done in the past—because they are quick and easy to establish to get version 1 of the product shipping. Often those continue to grow like weeds and before you know it–their are numerous internal interfaces; used as a method to send messages and data between applications and technology layers.
Maintenance and changes to applications using point-to-point interfaces are people intensive, tribal knowledge intensive and frustrating when large updates are needed or integration to other parts of the business needs to be introduced quickly. And, today, quick updates are critical to business growth.
Eventually, the organization will pay the toll for the code debt. I have seen organizations bring people back from retirement to help because no one else knows what was done–and they are too afraid to make a change
The complexity of managing, updating and refactoring an older code base is often underestimated by Executives. In turn, Developers are forced to find creative ways to split their code base in order to meet new demands for features. This only adds more complexity and costs.
The purpose of this post is to introduce or reinforce the core concepts and benefits to using a Microservices approach to your service oriented architecture; as a better way to architect and refactor applications.
The big idea behind “Microservices” is a set of organizing principles for designing, composing and factoring software for building responsive business services and functions that can scale with modern technology to serve customers worldwide.
A common approach many organizations take is to firmly insert middleware to manage their services in a publish-subscribe (pub/sub) model; which works great as long as the middleware is not used for processing business rules, business logic or complex orchestrations; since that defeats the purpose of agile (self-contained) service architecture in the first place.
The graphic (above) illustrates how some organizations position their services to leverage core business functions through middleware technology layers. The middleware layer is represented as an Enterprise Service Bus (ESB) and completed by using an API management system.
The main goal of Middleware is to lossely couple autonomous services though open standards to enable enterprise class interfaces between applications and data sources.
Being able to make a change to a back-end legacy application or data sources without impacting services means your organization can introduce change rapidly and avoid the time and cost of changing and testing interfaces.
Organizations have been using SOA concepts for over a decade. Benefits include:
- Platform independence with no vendor lock-in
- Better re-use of services to reduce cost and decrease time to delivery
- Introduce change without disrupting others
- Greater ROI with longer lasting software investments
There is less of an agreed upon definition for Microservices as there is a convergence of the following characteristics:
- Have a single responsbility
- Modelled around business functions, scenarios, solving a specific problem
- Independent and decentralized services—you can update a service without having to change another service or even knowing anything about peer services because interactions are isolated and strictly governed through APIs
- Implementation is focused on loosely coupled elements, scale, partitioning the code and state to provide flexibility and make upgrades and changes easier and quicker.
- Self-healing. Built to deal with unexpected failures. Awareness to handle physical machine outages, restart itself if it stops running, able to recover itself from a previous known good state.
- Denormalized database so that schema changes are loosely coupled to services or create separate data stores for each microservice.
- Services that can be updated and deployed independently—preferably with automated scripts
- Has a unique name (URL) that can be used to resolve its location
What Microservices is not focused on programming language, frameworks and especially not Middleware.
If you want to apply one simple rule to determine if what you are doing is indeed a Microservice model, it would be, that your service can be updated and deployed completely independent of making any change to any other service or a service bus (EBS)
Well-crafted Microservices use well-defined interfaces and protocols and encapsulate their own business rules to be middleware independent.
Here is a simple example to illustrate the concept of single responsibility per service:
If your bank were building with SOA, their services might be:
- Get User_profileAndUser_account_balance_ALL_AndUser_last_30_transactionsAndBill_Pay_DataAPI
If your Bank were building with microservices, their APIs might be:
- Submit Authenticate_FormService
- Get_Account_Last_30 Days_CheckingDataService
- Get_Account_Last_30 Days_SavingDataService
More APIs, single sets of responsibilities.
Reasons for Microservices:
- Enables DevOps (see related article why that is important)
- True agility by teasing out your business services from your legacy monolith so you can update them quickly with high quality and stay ahead of your competitors.
- Each team can run as fast as they can without being slowed down by the last team to check in clean code.
- Isolation (of independent services) bring higher availability and uptime SLAs. One issue doesn’t not crash the entire application.
- Better productivity, better focus on business process. Business SME’s and functional leads can drive innovation directly with the IT team
- Distributed architecture to scale globally.
Service Oriented Architecture (SOA) and Microservices
SOA and Microservices are very similar tactics and the difference between the two may come down to implementation approaches. Developing an application by exposing core application code or business functions as a web service with the same code model as your application including schema, contract, classes, modules and components is not adhering to the tenets of microservices; an application built around very small single service that is self-contained, independently deployable in a fully automated fashion, and generally exposed over a RESTful API.
Too many times I have seen organizations claim they are using SOA–only to find they have jam packed an XML payload with all the data that all interfaces need from the source application into a single web service. Then when the web service is modified the consumers have problems and need to update their parsing logic. I have observed more than one incident response team working late into the night looking for the reason an application is having an issue–only to find that a change made to the web service broke their interface.
In the digital era it is all about immediate responses in software to swiftly changing customer needs that is self-healing and automated. True autonomous microservices may be written in different programming languages and use different storage technologies. That is what a microservice approach to implementation gives you over SOA.
Large investments in SOA are not lost. De-compose, then re-compose them into individual services with a modest level of re-factoring work.
Smart End-Points and Dumb pipes:
A key tenant of microservices is that the service contains all of the business logic it needs to perform its function. The function of middleware in microservices architecture is to provide basic support for discovery, transport, and delivery of the service in a pub/sub model.
Think of Middleware as less an Enterprise Service Bus (ESB) and more of an API Gateway. Discovery, transport and delivery of a service, specifically any consumable interface that is web based (e.g. http based) would benefit from leveraging an API management system. Arguably, this can be viewed as middleware, but more appropriately viewed as a Service Gateway, as part of an orverall architecture, where service discovery, management (versions), contracts (subscribe), SLA, governance (publish) and reporting can be done without building that into the service itself, these are not capabilities found in middleware messaging systems (e.g. ESB). Generally these would be implemented in the service provider itself or provided by an API management layer or Gateway.
Inspired by Amazon and Netflix
Today, many point to Amazon as an organization that was able to conqueror services architecture and then turn around and sell it to the rest us of—but the world famous Amazon.com was not always as well crafted. Go back to the very beginning and Amazon.com code stack was a nicely tiered very tightly coupled components to form a monolith.
“If you go back to 2001”, Amazon, Sr. manager for product management Rob Brigham said at a 2015 conference, “The Amazon.com retail website was a large architectural monolith”. Amazon decided to decompose their monolithic architecture and pull apart functions into services. According to Brigham, “We went through the code and pulled out functional units that served a single purpose and we wrapped those with a web service interface.”
Like Amazon, at the beginning, Netflix had to transition from a traditional development monolithic DVD-rental application to a microservice architecture model using small teams that own a process from end-to-end, yet able to work together, to stream digital content to millions of Netflix customers.
Microsoft support for Microservices.
Azure Service Fabric is a platform you can leverage for building distributed systems at scale with low-latency in the cloud; and attaining the big benefits of running microservices at scale. It is a platform of system services for deployments, detecting and restarting failed services, state management and health monitoring. It also provides programming API’s for straightforward integration.
Azure Service Fabric is technology agnostic. Deeper information about Azure Service Fabric:
Lessons Learned from Digital innovators:
- Loosely couple database connections with Separate Data Stores. Using the same back-end data store means if one team updates the DB structure, other services using that structure will be impacted—which violates the ability to update services independently. Separate data stores makes Data Management more important because systems can get out of sync or have consistency issues or foreign keys change without notice. You’ll need a tool to find and fix inconsistencies.
- Have many, small teams that own their set of services end-to-end. Small teams are more agile, build deeper business knowledge and can better partner with their business functional counter parts.
- Use Automation. Use tools to auto build, deploy and test your services. Keep each microservice completely separate with no interdependent files—and enable a DevOps model with automated build, deploy and testing.
- Deploy in Containers. (See the advantages of containers here). Using containers is easier and faster for deployments. Containers also provide a model for scaling your application based on patterns of demand.
- No Sticky sessions. Focus on having enough servers not maintaining state. Servers running customer facing code should be interchangeable part of a pool or resources. Approach servers as stateless so you can use auto scaling to add more to the pool or automatically remove one if it stops working.
Sam’s book Building Microservices is a must read for those that are going down that path.
An overview of Sam Newman’s guiding principles for Microservices is below:
The battle cry for many large IT organizations for the next five years will be:
“Break your legacy, monolithic systems, even your web services into independently deployable microservices.”
When Microservices are combined with a DevOps approach using containers for deployment infrastructure and you will have a robust software factory with the ability of meeting business objectives rapidly to support a digital business strategy and disrupt your competitors.