45,59 €
A practical, comprehensive, and user-friendly approach to building microservices in Spring
This book is ideal for Spring developers who want to build cloud-ready, Internet-scale applications, and simple RESTful services to meet modern business demands.
The Spring Framework is an application framework and inversion of the control container for the Java platform. The framework's core features can be used by any Java application, but there are extensions to build web applications on top of the Java EE platform.
This book will help you implement the microservice architecture in Spring Framework, Spring Boot, and Spring Cloud. Written to the latest specifications of Spring that focuses on Reactive Programming, you'll be able to build modern, internet-scale Java applications in no time. The book starts off with guidelines to implement responsive microservices at scale. Next, you will understand how Spring Boot is used to deploy serverless autonomous services by removing the need to have a heavyweight application server.
Later, you'll learn how to go further by deploying your microservices to Docker and managing them with Mesos. By the end of the book, you will have gained more clarity on the implementation of microservices using Spring Framework and will be able to use them in internet-scale deployments through real-world examples.
The book takes a step-by-step approach on developing microservices using Spring Framework, Spring Boot, and a set of Spring Cloud components that will help you scale your applications.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 442
Veröffentlichungsjahr: 2017
This book is based on Spring Version 5.0 RC1
BIRMINGHAM - MUMBAI
< html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
Copyright © 2017 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: June 2016
Second edition: July 2017
Production reference: 1120717
ISBN 978-1-78712-768-5
www.packtpub.com
AuthorRajesh R V
Copy Editor
Zainab Bootwala
Reviewer
Aditya Abhay Halabe
Project Coordinator
Prajakta Naik
Commissioning Editor
Aaron Lazar
Proofreader
Safis Editing
Acquisition Editor
Chaitanya Nair
Indexer
Aishwarya Gangawane
ContentDevelopmentEditor
Siddhi Chavan
Graphics
Abhinash Sahu
Technical Editor
Abhishek Sharma
Production Coordinator
Shraddha Falebhai
Rajesh R VÂ is a seasoned IT architect with extensive experience in diversified technologies and more than 18 years of airline IT experience.
He received a degree in computer engineering from the University of Cochin, India, and he joined the JEE community during the early days of EJB. During his course as an architect, he worked on many large-scale, mission-critical projects, including the new generation Passenger Reservation System (iFly Res) and next generation Cargo Reservation System (Skychain, CROAMIS) in the Airline domain.
At present, as a chief architect at Emirates, Rajesh handles the solution architecture portfolio spread across various capabilities, such as JEE, SOA, NoSQL, IoT, cognitive computing, mobile, UI, and integration. At Emirates, the Open Travel Platform (OTP) architected by him earned the group the prestigious 2011 Red Hat Innovation Award in the Carved Out Costs category. In 2011, he introduced the innovative concept of the Honeycomb architecture based on the hexagonal architecture pattern for transforming the legacy mainframe system.
Rajesh has a deep passion for technology and architecture. He also holds several certifications, such as BEA Certified Weblogic Administrator, Sun Certified Java Enterprise Architect, Open Group Certified TOGAF practitioner, Licensed ZapThink Architect in SOA, and IASA global CITA-A Certified Architecture Specialist.
He has written Spring Microservices and reviewed Service-Oriented Java Business Integration by Packt Publishing.
I would like to thank everyone at Packt who I've worked closely with to make my dream come true. Thanks to the reviewers; their in-depth reviews helped improve the quality of this book.
This book would have never been possible without the encouragement from my excellent colleagues at Emirates with whom I worked with and learned from. A very special thanks goes to Neetan Chopra, Senior Vice President, and Thomas Benjamin, CTO, GE Aviation, for their constant support and help. Special thanks to Daniel Oor and Tomcy John for their help.
A heartfelt thanks goes to my wife, Saritha, for her tireless and unconditional support that helped me focus on this book. Thanks to my kids, Nikhil and Aditya. I have taken away a lot of the time that I'd spend playing with them to write this book. A huge thanks goes to my father, Ramachandran Nair, and my mother, Vasanthakumari, for their selfless support that helped me reach where I am today.
Aditya Abhay Halabe is a full-stack web application developer at Springer Nature's technology division. His primary technology stack includes Scala, Java, micro-web services, NOSQL databases, and multiple frameworks such as Spring, Play, and Angular. He has a very good understanding of Agile development, with continuous integration, which includes knowledge of DevOps, Docker, and automated deployment pipelines.
He is passionate about his work and likes to take on new challenges and responsibilities. Previously, Aditya has worked as a consultant with Oracle, and as a software developer with John Deere.
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1787127680. If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Downloading the color images of this book
Errata
Piracy
Questions
Demystifying Microservices
Evolution of microservices
Business demand as a catalyst for microservices evolution
Technology as a catalyst for microservices evolution
Imperative architecture evolution
What are Microservices?
Microservices - The honeycomb analogy
Principles of microservices
Single responsibility per service
Microservices are autonomous
Characteristics of microservices
Services are first class citizens
Characteristics of service in a microservice
Microservices are lightweight
Microservices with polyglot architecture
Automation in microservices environment
Microservices with a supporting ecosystem
Microservices are distributed and dynamic
Antifragility, fail fast, and self healing
Microservices examples
An example of a holiday portal
An example of a travel agent portal
Microservices benefits
Supports polyglot architecture
Enables experimentation and innovation
Elastically and selectively scalable
Allows substitution
Enables to build organic systems
Helps managing technology debt
Allowing co-existence of different versions
Supporting building self-organizing systems
Supporting event-driven architecture
Enables DevOps
Summary
Related Architecture Styles and Use Cases
Service-Oriented Architecture (SOA)
Service-oriented integration
Legacy modernization
Service-oriented application
Monolithic migration using SOA
Twelve-Factor Apps
Single code base
Bundle dependencies
Externalizing configurations
Backing services are addressable
Isolation between build, release, and run
Stateless, shared nothing processes
Expose services through port bindings
Concurrency for scale out
Disposability, with minimal overhead
Development, production parity
Externalizing logs
Package admin processes
Serverless computing
Lambda architecture
DevOps, Cloud, and Containers
DevOps as the practice and process for microservices
Cloud and Containers as the self-service infrastructure for microservices
Reactive microservices
A reactive microservice-based order management system
Microservice use cases
Microservices early adopters - Is there a common theme?
Monolithic migration as the common use case
Microservice frameworks
Summary
Building Microservices with Spring Boot
Setting up a development environment
Spring Boot for building RESTful microservices
Getting started with Spring Boot
Developing a Spring Boot microservice
Developing our first Spring Boot microservice
Testing Spring Boot microservice
HATEOAS-enabled Spring Boot microservice
Reactive Spring Boot microservices
Reactive microservices using Spring WebFlux
Understanding Reactive Streams
Publisher
Subscriber
Subscription
Processor
Reactive microservices using Spring Boot and RabbitMQ
Implementing security
Securing a microservice with basic security
Securing microservice with OAuth2
Enabling cross origin for microservices interactions
Spring Boot actuators for microservices instrumentation
Monitoring using JConsole
Monitoring using ssh
Adding a custom health module
Building custom metrics
Documenting microservices
Putting it all together - Developing a customer registration microservice example
Summary
Applying Microservices Concepts
Microservice design guidelines
Deciding microservice boundaries
Autonomous functions
Size of the deployable unit
Most appropriate function or sub-domain
Polyglot architecture
Selective scaling
Agile teams and co-development
Single responsibility
Replicability or changeability
Coupling and cohesion
Think of the microservice as a product
Designing communication styles
Synchronous style communication
Asynchronous style communication
How to decide which style to choose?
Orchestration of microservices
How many endpoints - one or many?
How many microservices per VM - one or multiple?
Rules engine - shared or embedded?
Role of BPM and workflows
Can microservices share a data store?
Can microservices be headless?
Deciding transaction boundaries
Altering use cases to simplify transactional requirements
Distributed transaction scenarios
Service endpoint design consideration
Contract design
Protocol selection
Message oriented services
HTTP and REST endpoints
Optimized Communication Protocols
API documentations
Handling shared libraries
User interfaces in microservices
Use of API gateways in microservices
Use of ESB and iPaaS with microservices
Service versioning considerations
Design for cross origin
Handling shared reference data
Microservices and bulk operations
Summary
Microservices Capability Model
Microservices capability model
Core capabilities
Service listeners and libraries
Storage capability
Service implementation
Service endpoint
Infrastructure capabilities
Cloud
Container runtime
Container orchestration
Supporting capabilities
Service gateway
Software-defined load balancer
Central log management
Service discovery
Security service
Service configuration
Ops monitoring
Dependency management
Data lake
Reliable messaging
Process and governance capabilities
DevOps
Automation tools
Container registry
Microservice documentation
Reference architecture and libraries
Microservices maturity model
Level 0 - Traditional
Level 1 - Basic
Level 2 - Intermediate
Level 3 - Advanced
Entry points for adoption
Summary
Microservices Evolution – A Case Study
Understanding the PSS application
Business process view
Functional view
Architecture view
Design view
Implementation view
Deployment view
Death of the monolith
Pain points
Stopgap fix
Retrospection
Precedence on data sharing over modularity
Single monolithic database
Native queries
Stored procedures
Compromised on domain boundaries
Microservices to the rescue - a planned approach for migration
The business case
Migration approach
Identification of microservices' boundaries
Analyze dependencies
Events as opposed to query
Events as opposed to synchronous updates
Challenge requirements
Challenge service boundaries
Final dependency graph
Prioritizing microservices for migration
Data synchronization during migration
Managing reference data
User interfaces and web applications
Session handling and security
Test strategy
Building ecosystem capabilities
Migrate modules only if required
Internal layering of microservices
Orchestrating microservices
Integration with other systems
Managing shared libraries
Handling exceptions
Target implementation
Implementation projects
Running and testing the project
Potential next steps
Summary
Scale Microservices with Spring Cloud Components
What is Spring Cloud?
Spring Cloud releases
Setting up the environment for the BrownField PSS
Spring Cloud Config
Building microservices with Config Server
Setting up the Config Server
Understanding the Config Server URL
Accessing the Config Server from clients
Handling configuration changes
Spring Cloud Bus for propagating configuration changes
Setting up high availability for the Config Server
Monitoring Config Server health
Config Server for configuration files
Completing changes to use Config Server
Eureka for registration and discovery
Understanding dynamic service registration and discovery
Understanding Eureka
Setting up the Eureka Server
High availability for Eureka
Zuul proxy as the API Gateway
Setting up Zuul
High availability of Zuul
High availability of Zuul when the client is also a Eureka Client
High availability when client is not a Eureka Client
Completing Zuul for all other services
Streams for reactive microservices
Protecting microservices with Spring Cloud Security
Summarising the BrownField PSS architecture
Summary
Logging and Monitoring Microservices
Understanding log management challenges
Centralized logging solution
Selection of logging solutions
Cloud services
Off-the-shelf solutions
Best of the breed integration
Log shippers
Log stream processors
Log storage
Dashboards
Custom logging implementation
Distributed tracing with Spring Cloud Sleuth
Monitoring microservices
Monitoring challenges
Monitoring tools
Monitoring microservice dependency
Spring Cloud Hystrix for fault-tolerant microservices
Aggregate Hystrix streams with Turbine
Data analysis using Data Lake
Summary
Containerizing Microservices with Docker
Understanding gaps in the BrownField PSS microservices
What are containers?
Difference between VM and containers
Benefits of containers
Microservices and containers
Introduction to Docker
Key components of Docker
The Docker daemon
The Docker client
The Docker image
The Docker container
The Docker registry
Dockerfile
Deploying microservices into Docker
Running RabbitMQ on Docker
Using the Docker registry
Setting up the Docker Hub
Publish microservices to the Docker Hub
Microservices on Cloud
Installing Docker on AWS EC2
Running BrownField services on EC2
Future of containerization
Summary
Scaling Dockerized Microservices with Mesos and Marathon
Scaling microservices
Understanding autoscaling
The missing pieces
Container orchestration
Why is container orchestration is important
What does container orchestration do?
Relationship with microservices
Relationship with virtualization
Container orchestration solutions
Docker Swarm
Kubernetes
Apache Mesos
HashiCorp Nomad
CoreOS Fleet
Container orchestration with Mesos and Marathon
Mesos in details
Mesos architecture
Marathon
Implementing Mesos and Marathon with DCOS
Implementing Mesos and Marathon for BrownField microservices
Installing Mesos, Marathon, and related components
Running Mesos and Marathon
Preparing BrownField PSS services
Deploying BrownField PSS services
Summary
Microservice Development Life Cycle
Practice points for microservice development
Understanding business motivation and value
Change the mindset from project to product development
Choosing the right development philosophy
Using the concept of minimum viable product (MVP)
Overcoming the legacy hotspot
Establishing self-organizing teams
Building the self-service cloud
Building a microservices ecosystem
DevOps as a life cycle process
Value driven planning
Continuous monitoring and feedback
Automating development cycle
Development
Integration
Testing
Sanity tests
Regression testing
Functional testing
Acceptance testing
Performance testing
Real user flow simulation or Journey testing
Security testing
Exploratory testing
A/B testing, Canary testing, and blue-green deployments
Other non-functional tests
Testing in production (TiP)
Antifragility testing
Deployment
Monitoring and feedback
Configuration management
Microservices development governance, reference architectures, and libraries
Summary
Microservices is an architecture style and a pattern in which complex systems are decomposed into smaller services that work together to form larger business services. Microservices are services that are autonomous, self-contained, and independently deployable. In today's world, many enterprises use microservices as the default standard to build large service-oriented enterprise applications.
Spring Framework has been a popular programming framework for the developer community for many years. Spring Boot removed the need to have a heavyweight application container, and provides a means to deploy lightweight, serverless applications. Spring Cloud combines many Netflix OSS components and provides an ecosystem to run and manage large-scale microservices. It provides capabilities such as load balancing, service registry, monitoring, Service Gateway, and so on.
However, microservices comes with its own challenges, such as monitoring, managing, distributing, scaling, discovering, and more, especially when deploying at scale. Adopting microservices without addressing common microservices challenges will lead to catastrophic results. The most important part of this book is a technology-agnostic microservices capability model that helps address all common microservice challenges.
The goal of this book  is to enlighten readers with a pragmatic approach and provide guidelines to implement responsive microservices at scale. This book will give a holistic view of capabilities that are required to build microservices with examples. This book takes a deep dive into Spring Boot, Spring Cloud, Docker, Mesos, and Marathon. Upon completion of this book, you will understand how Spring Boot will be used to deploy autonomous services by removing the need to have a heavyweight application server. You will also learn different Spring Cloud capabilities, as well as realize the use of Docker for containerization, Mesos, and Marathon for compute resource abstraction and cluster-wide control.
I am sure you will enjoy each and every section of this book. Also, I honestly believe that this book adds tremendous value in successfully conceiving microservices into your business. Throughout this book, I have used practical aspects of microservices implementation by providing a number of examples, including a case study from the travel domain. At the end of this book, you will have learned how to implement microservice architectures using Spring Framework, Spring Boot, and Spring Cloud. These are battle-tested, robust tools for developing and deploying scalable microservices. Written to the latest specifications of Spring, with the help of this book, you’ll be able to build modern, internet-scale Java applications in no time.
Chapter 1, Demystifying Microservices, gives you an introduction to microservices. This chapter covers the background, evaluation, and fundamental concepts of microservices.
Chapter 2, Related Architecture Styles and Use Cases, covers the relationship with Service-Oriented Architecture, the concepts of cloud native and Twelve Factor applications, and explains some of the common use cases.
Chapter 3, Building Microservices with Spring Boot, introduces building REST and message-based microservices using the Spring Framework and how to wrap them with Spring Boot. In addition, we will also explore some core capabilities of Spring Boot.
Chapter 4, Applying Microservices Concepts, explains the practical aspects of microservices implementation by detailing the challenges that developers face with enterprise-grade microservices.
Chapter 5, Microservices Capability Model, introduces a capability model required to successfully manage a microservices ecosystem. This chapter also describes a maturity assessment model, which will be useful when adopting microservices at enterprise level.
Chapter 6, Microservices Evolution – A Case Study, takes you to a real-world case study of microservices evolution by introducing BrownField Airline. Using the case study, explains how to apply microservices concepts learned in the previous chapter.
Chapter 7, Scale Microservices with Spring Cloud Components, shows you how to scale previous examples using Spring Cloud stack capabilities. It details the architecture and different components of Spring Cloud and how they integrate together.
Chapter 8, Logging and Monitoring Microservices, covers the importance of logging and monitoring aspects when developing microservices. Here, we look at the details of some of the best practices when using microservices, such as centralized logging and monitoring capabilities using open source tools and how to integrate them with Spring projects.
Chapter 9, Containerizing Microservices with Docker, explains containerization concepts in the context of microservices. Using Mesos and Marathon, it demonstrates next-level implementation to replace the custom life cycle manager for large deployments.
Chapter 10, Scaling Dockerized Microservices with Mesos and Marathon, explains auto-provisioning and deployment of microservices. Here, we will also learn how to use Docker containers in the preceding example for large-scale deployments.
Chapter 11, Microservices Development Life Cycle, covers the process and practices of microservices development. The importance of DevOps and continuous delivery pipelines are also explained in this chapter.
Chapter 3, Building Microservices with Spring Boot, introduces Spring Boot, which requires the following software components to test the code:
JDK 1.8
Spring Tool Suite 3.8.2 (STS)
Maven 3.3.1
Spring Framework 5.0.0.RC1
Spring Boot 2.0.0. SNAPSHOT
spring-boot-cli-2.0.0.SNAPSHOT-bin.zip
Rabbit MQ 3.5.6
FakeSMTP 2.0
In Chapter 7, Scale Microservices with Spring Cloud Components, you will learn about the Spring Cloud project. This requires the following software component, in addition to those previously mentioned:
Spring Cloud Dalston RELEASE
In Chapter 8, Logging and Monitoring Microservices, we will see how centralized logging can be implemented for microservices. This requires the following software stack:
elasticsearch-1.5.2
kibana-4.0.2-darwin-x64
logstash-2.1.2
Chapter 9, Containerizing Microservices with Docker, demonstrates how we can use Docker for microservices deployments. This requires the following software components:
Docker version (17.03.1-ce)
Docker Hub
Chapter 10, Scaling Dockerized Microservices with Mesos and Marathon, uses Mesos and Marathon to deploy Dockerized microservices into an autoscalable cloud. The following software components are required for this purpose:
Mesos version 1.2.0
Docker version 17.03.1-ce
Marathon version 3.4.9
This book will be interesting for architects who want to know how to design robust internet-scale microservices in Spring Framework, Spring Boot, and Spring Cloud, and manage them using Docker, Mesos, and Marathon. The capability model will help architects device solutions even beyond the tools and technologies discussed in this book.
This book is primarily for Spring developers who are looking to build cloud-ready, internet-scale applications to meet modern business demands. The book will help developers understand what exactly microservices are, and why they are important in today's world, by examining a number of real-world use cases and hand-on code samples. Developers will understand how to build simple Restful services and organically grow them to truly enterprise-grade microservices ecosystems.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR / 7-Zip for Windows
Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Spring-5.0-Microservices-Second-Edition. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/Spring5.0MicroservicesSecondEdition_ColorImages.
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
Microservices is an architecture style and an approach for software development to satisfy modern business demands. Microservices are not invented, it is more of an evolution from the previous architecture styles.
We will start the chapter by taking a closer look at the evolution of microservices architecture from the traditional monolithic architectures. We will also examine the definition, concepts, and characteristics of microservices.
By the end of this chapter, you will have learned about the following:
Evolution of microservices
Definition of microservices architecture with examples
Concepts and characteristics of microservices architecture
Microservices is one of the increasingly popular architecture patterns next to Service Oriented Architecture (SOA), complemented by DevOps and Cloud. Its evolution has been greatly influenced by the disruptive digital innovation trends in modern business and the evolution of technology in the last few years. We will examine these two catalysts--business demands and technology--in this section.
In this era of digital transformation, enterprises are increasingly adopting technologies as one of the key enablers for radically increasing their revenue and customer base. Enterprises are primarily using social media, mobile, cloud, big data, and Internet of Things (IoT) as vehicles for achieving the disruptive innovations. Using these technologies, enterprises are finding new ways to quickly penetrate the market, which severely pose challenges to the traditional IT delivery mechanisms.
The following graph shows the state of traditional development and microservices against the new enterprise challenges, such as agility, speed of delivery, and scale:
Microservices promises more agility, speed of delivery, and scale compared to traditional monolithic applications.
Gone are the days where businesses invested in large application developments with turnaround times of a few years. Enterprises are no longer interested in developing consolidated applications for managing their end-to-end business functions as they did a few years ago.
The following graph shows the state of traditional monolithic application and microservices in comparison with the turnaround time and cost:
Microservices provides an approach for developing quick and agile applications, resulting in a lesser overall cost.
Today, for instance, airlines are not investing in rebuilding their core mainframe reservation systems as another monolithic monster. Financial institutions are not rebuilding their core banking systems. Retailers and other industries are not rebuilding heavyweight supply chain management applications, such as their traditional ERP's. Focus has been shifted from building large applications to building quick win, point solutions that cater to the specific needs of the business in the most agile way possible.
Let's take an example of an online retailer running with a legacy monolithic application. If the retailer wants to innovate their sales by offering their products personalized to a customer based on the customer's past shopping preferences and much more, or they want to enlighten customers by offering products to customer based on propensity to buy a product.
In such cases, enterprises want to quickly develop a personalization engine or an offer engine based on their immediate needs, and plug them into their legacy application, as shown here:
As shown in the preceding diagram, rather than investing on rebuilding the Core Legacy System, this will either be done by passing the responses through the new functions, as shown in the diagram marked A, or modifying the Core Legacy System to call out these functions as part of the processing, as shown in the diagram marked B. These functions are typically written as microservices.
This approach gives organizations a plethora of opportunities to quickly try out new functions with lesser cost in an experimental mode. Business can later validate key performance indicators change or replace these implementations if required.
Modern architectures are expected to maximize the ability to replace its parts and minimize the cost of replacing them. Microservices' approach is a means to achieve this.
Emerging technologies have made us rethink the way we build software systems. For example, a few decades ago, we couldn't even imagine a distributed application without a two-phase commit. Later, NoSQL databases made us think differently.
Similarly, these kinds of paradigm shifts in technology have reshaped all layers of software architecture.
The emergence of HTML 5, CSS3, and the advancement of mobile applications repositioned user interfaces. Client-side JavaScript frameworks, such as Angular, Ember, React, Backbone, and more, are immensely popular due to their capabilities around responsive and adaptive designs.
With cloud adoptions steamed into the mainstream, Platform as a Services (PaaS) providers, such as Pivotal CF, AWS, Sales Force, IBM Bluemix, Redhat OpenShift, and more, made us rethink the way we build middleware components. The container revolution created by Docker radically influenced the infrastructure space. Container orchestration tools, such as Mesosphere DCOS, made infrastructure management much easier. Serverless added further easiness in application managements.
Integration landscape has also changed with the emerging IntegrationPlatform as a Services (iPaaS), such as Dell Boomi, Informatica, MuleSoft, and more. These tools helped organizations stretch integration boundaries beyond the traditional enterprise.
NoSQL and NewSQL have revolutionized the space of the database. A few years ago, we had only a few popular databases, all based on relational data modeling principles. Today, we have a long list of databases: Hadoop, Cassandra, CouchDB, Neo 4j, and NuoDB, to name a few. Each of these databases addresses certain specific architectural problems.
Application architecture has always been evolving alongside with demanding business requirements and evolution of technologies.
Different architecture approaches and styles, such as mainframes, client server, n-tier, and service oriented were popular at different times. Irrespective of the choice of architecture styles, we always used to build one or the other forms of monolithic architectures. Microservices architecture evolved as a result of modern business demands, such as agility, speed of delivery, emerging technologies, and learning from previous generations of architectures:
Microservices help us break the boundaries of the monolithic application and build a logically independent smaller system of systems, as shown in the preceding diagram.
If we consider the monolithic application as a set of logical subsystems encompassed with a physical boundary, microservices are a set of independent subsystems with no enclosing physical boundary.
Microservices are an architectural style used by many organizations today as a game changer to achieve high degrees of agility, speed of delivery, and scale. Microservices gives us a way to develop physically separated modular applications.
Microservices are not invented. Many organizations, such as Netflix, Amazon, and eBay had successfully used the divide and conquer technique for functionally partitioning their monolithic applications into smaller atomic units, each performing a single function. These organizations solved a number of prevailing issues they were experiencing with their monolithic application. Following the success of these organizations, many other organizations started adopting this as a common pattern for refactoring their monolithic applications. Later, evangelists termed this pattern microservices architecture.
Microservices originated from the idea of Hexagonal Architecture, which was coined by Alister Cockburn back in 2005. Hexagonal Architecture, or Hexagonal pattern, is also known as the Ports and Adapters pattern.
Read more about Hexagonal Architecture here:http://alistair.cockburn.us/Hexagonal+architecture
In simple terms, Hexagonal architecture advocates to encapsulate business functions from the rest of the world. These encapsulated business functions are unaware of their surroundings. For example, these business functions are not even aware of input devices or channels and message formats used by those devices. Ports and adapters at the edge of these business functions convert messages coming from different input devices and channels to a format that is known to the business function. When new devices are introduced, developers can keep adding more and more ports and adapters to support those channels without touching business functions. One may have as many ports and adapters to support their needs. Similarly, external entities are not aware of business functions behind these ports and adapters. They will always interface with these ports and adapters. By doing so, developers enjoy the flexibility to change channels and business functions without worrying too much about future proofing interface designs.
The following diagram shows the conceptual view of Hexagonal Architecture:
In the preceding diagram, the application is completely isolated and exposed through a set of frontend adapters, as well as a set of backend adapters. Frontend adaptors are generally used for integrating UI and other APIs, whereas backend adapters are used for connecting to various data sources. Ports and adapters on both sides are responsible for converting messages coming in and going out to appropriate formats expected by external entities. Hexagonal architecture was the inspiration for microservices.
When we look for a definition for microservices, there is no single standard way of describing them. Martin Fowler defines microservices as follows:
The definition used in this book is as follows:
The preceding diagram depicts a traditional n-tier application architecture, having a Presentation Layer, Business Layer, and Database Layer. Modules A, B, and C represent three different business capabilities. The layers in the diagram represent separation of architecture concerns. Each layer holds all three business capabilities pertaining to that layer. The presentation layer has web components of all three modules, the business layer has business components of all three modules, and the database host tables of all three modules. In most cases, layers are physically spreadable, whereas modules within a layer are hardwired.
Let's now examine a microservices-based architecture:
As we can see in the preceding diagram, the boundaries are inversed in the microservices architecture. Each vertical slice represents a microservice. Each microservice will have its own presentation layer, business layer, and database layer. Microservices are aligned towards business capabilities. By doing so, changes to one microservice does not impact others.
There is no standard for communication or transport mechanisms for microservices. In general, microservices communicate with each other using widely adopted lightweight protocols, such as HTTP and REST, or messaging protocols, such as JMS or AMQP. In specific cases, one might choose more optimized communication protocols, such as Thrift, ZeroMQ, Protocol Buffers, or Avro.
Since microservices are more aligned to business capabilities and have independently manageable life cycles, they are the ideal choice for enterprises embarking on DevOps and cloud. DevOps and cloud are two facets of microservices.
DevOps is an IT realignment to narrow the gap between traditional IT development and operations for better efficiency.
Read more about DevOps at http://dev2ops.org/2010/02/what-is-devops/.
A honeycomb is an ideal analogy for representing the evolutionary microservices architecture:
In the real world, bees build a honeycomb by aligning hexagonal wax cells. They start small, using different materials to build the cells. Construction is based on what is available at the time of building. Repetitive cells form a pattern, and result in a strong fabric structure. Each cell in the honeycomb is independent, but also integrated with other cells. By adding new cells, the honeycomb grows organically to a big, solid structure. The content inside the cell is abstracted and is not visible outside. Damage to one cell does not damage other cells, and bees can reconstruct those cells without impacting the overall honeycomb.
In this section, we will examine some of the principles of the microservices architecture. These principles are a must have when designing and developing microservices. The two key principles are single responsibility and autonomous.
The single responsibility principle is one of the principles defined as part of the SOLID design pattern. It states that a unit should only have one responsibility.
Read more about the SOLID design pattern at http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign.
It implies that a unit, either a class, a function, or a service, should have only one responsibility. At no point do two units share one responsibility, or one unit perform more than one responsibility. A unit with more than one responsibility indicates tight coupling:
As shown in the preceding diagram, Customer, Product, and Order are different functions of an e-commerce application. Rather than building all of them into one application, it is better to have three different services, each responsible for exactly one business function, so that changes to one responsibility will not impair the others. In the preceding scenario, Customer, Product, and Order were treated as three independent microservices.
Microservices are self-contained, independently deployable, and autonomous services that take full responsibility of a business capability and its execution. They bundle all dependencies including the library dependencies; execution environments, such as web servers and containers; or virtual machines that abstract the physical resources.
One of the major differences between microservices and SOA is in its level of autonomy. While most of the SOA implementations provide the service-level abstraction, microservices go further and abstract the realization and the execution environment.
In traditional application developments, we build a war or a ear, then deploy it into a JEE application server, such as JBoss, Weblogic, WebSphere, and more. We may deploy multiple applications into the same JEE container. In the microservices approach, each microservice will be built as a fat jar embedding all dependencies and run as a standalone Java process:
Microservices may also get their own containers for execution, as shown in the preceding diagram. Containers are portable, independently manageable, and lightweight runtime environments. Container technologies, such as Docker, are an ideal choice for microservices deployments.
The microservices definition discussed earlier in this chapter is arbitrary. Evangelists and practitioners have strong, but sometimes, different opinions on microservices. There is no single, concrete, and universally accepted definition for microservices. However, all successful microservices implementations exhibit a number of common characteristics. Therefore, it is important to understand these characteristics rather than sticking to theoretical definitions. Some of the common characteristics are detailed in this section.
In the microservices world, services are first class citizens. Microservices expose service endpoints as APIs and abstract all their realization details. The internal implementation logic, architecture, and technologies, including programming language, database, quality of services mechanisms, and more, are completely hidden behind the service API.
Moreover, in the microservices architecture, there is no more application development, instead organizations will focus on service development. In most enterprises, this requires a major cultural shift in the way applications are built.
In a customer profile microservice, the internals, such as data structure, technologies, business logic, and so on, will be hidden. It wont be exposed or visible to any external entities. Access will be restricted through the service endpoints or APIs. For instance, customer profile microservices may expose register customer and get customers as two APIs for others to interact.
Since microservices are more or less like a flavor of SOA, many of the service characteristics defined in the SOA are applicable to microservices as well.
The following are some of the characteristics of services that are applicable to microservices as well:
Service contract
: Similar to SOA, microservices are described through well-defined service contracts. In the microservices world, JSON and REST are universally accepted for service communication. In case of JSON/REST, there are many techniques used to define service contracts. JSON Schema, WADL, Swagger, and RAML are a few examples.
Loose coupling
: Microservices are independent and loosely coupled. In most cases, microservices accept an event as input and respond with another event. Messaging, HTTP, and REST are commonly used for interaction between microservices. Message-based endpoints provide higher levels of decoupling.
Service abstraction
: In microservices, service abstraction is not just abstraction of service realization, but also provides complete abstraction of all libraries and environment details, as discussed earlier.
Service reuse
: Microservices are course grained reusable business services. These are accessed by mobile devices and desktop channels, other microservices, or even other systems.
Statelessness
: Well-designed microservices are a stateless, shared nothing with no shared state, or conversational state maintained by the services. In case there is a requirement to maintain state, they will be maintained in a database, perhaps in-memory.
Services are discoverable
: Microservices are discoverable. In a typical microservices environment, microservices self-advertise their existence and make themselves available for discovery. When services die, they automatically take themselves out from the microservices ecosystem.
Service interoperability
: Services are interoperable as they use standard protocols and message exchange standards. Messaging, HTTP, and more are used as the transport mechanism. REST/JSON is the most popular method to develop interoperable services in the microservices world. In cases where further optimization is required on communications, then other protocols such as Protocol Buffers, Thrift, Avro, or Zero MQ could be used. However, use of these protocols may limit the overall interoperability of the services.
Service Composeability
: Microservices are composeable. Service composeability is achieved either through service orchestration or service choreography.
More details on SOA principles can be found at http://serviceorientation.com/serviceorientation/index.
Well-designed microservices are aligned to a single business capability; therefore, they perform only one function. As a result, one of the common characteristics we see in most of the implementations are microservices with smaller footprints.
When selecting supporting technologies, such as web containers, we will have to ensure that they are also lightweight so that the overall footprint remains manageable. For example, Jetty or Tomcat are better choices as application containers for microservices as compared to more complex traditional application servers, such as Weblogic or WebSphere.
Container technologies such as Docker also helps us keep the infrastructure footprint as minimal as possible compared to hypervisors such as VMware or Hyper-V.
As shown in the preceding diagram, microservices are typically deployed in Docker containers, which encapsulate the business logic and needed libraries. This helps us quickly replicate the entire setup on a new machine, a completely different hosting environment, or even move across different cloud providers. Since there is no physical infrastructure dependency, containerized microservices are easily portable.
Since microservices are autonomous and abstract everything behind the service APIs, it is possible to have different architectures for different microservices. A few common characteristics that we see in microservices implementations are as follows:
Different services use different versions of the same technologies. One microservice may be written on Java 1.7 and another one could be on Java 1.8.
Different languages for developing different microservices, such as one microservice in Java and another one in
Scala
.
Different architectures such as one microservice using
Redis
cache to serve data while another microservice could use MySQL as a persistent data store.
A polyglot language scenario is depicted in the following diagram:
In the preceding example, since Hotel Search is expected to have high transaction volumes with stringent performance requirements, it is implemented using Erlang. In order to support predictive search, Elastic Search is used as the data store. At the same time, Hotel Booking needs more ACID transactional characteristics. Therefore, it is implemented using MySQL and Java. The internal implementations are hidden behind service endpoints defined as REST/JSON over HTTP.
Most of the microservices implementations are automated to a maximum, ranging from development to production.
Since microservices break monolithic applications into a number of smaller services, large enterprises may see a proliferation of microservices. Large numbers of microservices are hard to manage until and unless automation is in place. The smaller footprint of microservices also helps us automate the microservices development to deployment life cycle. In general, microservices are automated end to end, for example, automated builds, automated testing, automated deployment, and elastic scaling:
As indicated in the diagram, automations are typically applied during the development, test, release, and deployment phases.
Different blocks in the preceding diagram are explained as follows:
The development phase will be automated using version control tools, such as Git, together with
continuous
integration
(
CI
) tools, such as Jenkins, Travis CI, and more. This may also include code quality checks and automation of unit testing. Automation of a full build on every code check-in is also achievable with microservices.
The testing phase will be automated using testing tools such as
Selenium
,
Cucumber
, and other
AB testing strategies
. Since microservices are aligned to business capabilities, the number of test cases to automate will be fewer compared to the monolithic applications; hence, regression testing on every build also becomes possible.
Infrastructure provisioning will be done through container technologies, such as Docker, together with release management tools, such as Chef or Puppet, and configuration management tools, such as Ansible. Automated deployments are handled using tools such as Spring Cloud,
Kubernetes
,
Mesos
, and Marathon.
Most of the large scale microservices implementations have a supporting ecosystem in place. The ecosystem capabilities include DevOps processes, centralized log management, service registry, API gateways, extensive monitoring, service routing, and flow control mechanisms:
Microservices work well when supporting capabilities are in place, as represented in the preceding diagram.
Successful microservices implementations encapsulate logic and data within the service. This results in two unconventional situations:
Distributed data and logic
Decentralized governance
Compared to traditional applications, which consolidate all logic and data into one application boundary, microservices decentralize data and logic. Each service, aligned to a specific business capability, owns its own data and logic:
The dotted line in the preceding diagram implies the logical monolithic application boundary. When we migrate this to microservices, each microservice, A, B, and C, creates its own physical boundaries.
Microservices don't typically use centralized governance mechanisms the way they are used in SOA. One of the common characteristics of microservices implementations are that they are not relaying on heavyweight enterprise-level products, such as an Enterprise Service Bus (ESB). Instead, the business logic and intelligence are embedded as a part of the services themselves.
A retail example with ESB is shown as follows:
A typical SOA implementation is shown in the preceding diagram. Shopping Logic is fully implemented in the ESB by orchestrating different services exposed by Customer, Order, and Product. In the microservices approach, on the other hand, shopping itself will run as a separate microservice, which interacts with Customer, Product, and Order in a fairly decoupled way.
SOA implementations are heavily relaying on static registry and repository configurations to manage services and other artifacts. Microservices bring a more dynamic nature into this. Hence, a static governance approach is seen as an overhead in maintaining up-to-date information. This is why most of the microservices implementations use automated mechanisms to build registry information dynamically from the runtime topologies.
Antifragility is a technique successfully experimented with at Netflix. It is one of the most powerful approaches to build fail-safe systems in modern software development.
The antifragility concept is introduced by Nassim Nicholas Taleb in his book, Antifragile: Things That Gain from Disorder.
In the antifragility practice, software systems are consistently challenged. Software systems evolve through these challenges, and, over a period of time, get better and better to withstand these challenges. Amazon's Game Day exercise and Netflix's Simian Army are good examples of such antifragility experiments.
Fail Fast is another concept used to build fault-tolerant, resilient systems. This philosophy advocates systems that expect failures versus building systems that never fail. Importance has to be given to how quickly the system can fail, and, if it fails, how quickly it can recover from that failure. With this approach, the focus is shifted from Mean Time Between Failures (MTBF) to Mean Time To Recover (MTTR). A key advantage of this approach is that if something goes wrong, it kills itself, and the downstream functions won’t be stressed.
Self-Healing is commonly used in microservices deployments, where the system automatically learns from failures and adjusts itself. These systems also prevent future failures.
There is no one size fits all approach when implementing microservices. In this section, different examples are analyzed to crystalize the microservices concept.
In the first example, we will review a holiday portal--Fly By Points. Fly By Points
