SG 248275
SG 248275
SG 248275
Shishir Narain
Ramratan Vennam
Kameswara Eati
Carlos M Ferreira
Dejan Glozic
Vasfi Gucer
Manav Gupta
Sunil Joshi
Valerie Lampkin
Marcelo Martins
Redbooks
SG24-8275-00
Note: Before using this information and the product it supports, read the information in Notices on
page vii.
Contents
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii
IBM Redbooks promotions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Now you can become a published author, too . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Stay connected to IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
Part 1. Introducing the microservices architectural style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 1. Motivations for microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1 What are microservices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.1 Small and focused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.2 Loosely coupled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.3 Language-neutral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.4 Bounded context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.5 Comparing microservices and monolithic architectures . . . . . . . . . . . . . . . . . . . . . 6
1.2 Benefits from microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.1 Enterprise solutions context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.2 Challenges with monolithic architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.3 Developer perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.4 Tester perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.5 Business owner perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.6 Service management perspective. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 What to avoid with microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.1 Dont start with microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.2 Dont even think about microservices without DevOps . . . . . . . . . . . . . . . . . . . . . 11
1.3.3 Dont manage your own infrastructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.4 Dont create too many microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.5 Dont forget to keep an eye on the potential latency issue . . . . . . . . . . . . . . . . . . 12
1.4 How is this different than service-oriented architecture?. . . . . . . . . . . . . . . . . . . . . . . . 12
1.5 Case studies and most common architectural patterns . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5.1 An e-commerce discount site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.2 Financial services company . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.3 Large brick-and-mortar retailer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.6 Example scenarios using microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6.1 Cloud Trader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6.2 Online Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6.3 Acme Air . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Chapter 2. Elements of a microservices architecture . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1 Characteristics of microservices architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Business-oriented . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.2 Design for failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.3 Decentralized data management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.4 Discoverability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
20
20
21
23
24
iii
iv
24
27
28
29
29
31
32
33
33
34
37
38
39
40
40
40
40
41
41
43
44
44
45
46
47
47
48
50
51
51
55
57
58
59
63
66
68
69
74
76
76
78
79
79
81
81
83
85
86
86
87
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
123
124
124
125
126
127
128
129
129
129
130
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance
capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
8.1 The original Acme Air monolithic application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
8.1.1 Deploying the Acme Air application in monolithic mode . . . . . . . . . . . . . . . . . . . 133
8.2 Redesigning application to use microservices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
8.2.1 Deploying the Acme Air application in microservices mode . . . . . . . . . . . . . . . . 140
8.3 Adding Hystrix to monitor services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
8.3.1 Deploying the Hystrix Dashboard to Bluemix . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Contents
Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Help from IBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
vi
147
147
147
147
148
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features described in this document in other countries. Consult
your local IBM representative for information about the products and services currently available in your area.
Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product, program, or service that does
not infringe any IBM intellectual property right may be used instead. However, it is the users responsibility to
evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document. The
furnishing of this document does not grant you any license to these patents. You can send license inquiries, in
writing, to:
IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785 U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION
PROVIDES THIS PUBLICATION AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of
express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made
to the information herein; these changes will be incorporated in new editions of the publication. IBM may make
improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time
without notice.
Any references in this information to non-IBM websites are provided for convenience only and do not in any
manner serve as an endorsement of those websites. The materials at those websites are not part of the
materials for this IBM product and use of those websites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring
any obligation to you.
Any performance data contained herein was determined in a controlled environment. Therefore, the results
obtained in other operating environments may vary significantly. Some measurements may have been made
on development-level systems and there is no guarantee that these measurements will be the same on
generally available systems. Furthermore, some measurements may have been estimated through
extrapolation. Actual results may vary. Users of this document should verify the applicable data for their
specific environment.
Information concerning non-IBM products was obtained from the suppliers of those products, their published
announcements or other publicly available sources. IBM has not tested those products and cannot confirm the
accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the
capabilities of non-IBM products should be addressed to the suppliers of those products.
This information contains examples of data and reports used in daily business operations. To illustrate them
as completely as possible, the examples include the names of individuals, companies, brands, and products.
All of these names are fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrate programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs in
any form without payment to IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating platform for which the sample
programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore,
cannot guarantee or imply reliability, serviceability, or function of these programs.
vii
Trademarks
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines
Corporation in the United States, other countries, or both. These and other IBM trademarked terms are
marked on their first occurrence in this information with the appropriate symbol ( or ), indicating US
registered or common law trademarks owned by IBM at the time this information was published. Such
trademarks may also be registered or common law trademarks in other countries. A current list of IBM
trademarks is available on the Web at http://www.ibm.com/legal/copytrade.shtml
The following terms are trademarks of the International Business Machines Corporation in the United States,
other countries, or both:
Bluemix
CICS
Cloudant
Concert
DataPower
DB2
DOORS
Global Business Services
System z
Tealeaf
Tivoli
WebSphere
Worklight
viii Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Download
Now
Android
iOS
ibm.com/Redbooks
About Redbooks
Preface
Microservices is an architectural style in which large, complex software applications are
composed of one or more smaller services. Each of these microservices focuses on
completing one task that represents a small business capability. These microservices can be
developed in any programming language. They communicate with each other using
language-neutral protocols, such as Representational State Transfer (REST), or messaging
applications, such as IBM MQ Light.
This IBM Redbooks publication gives a broad understanding of this increasingly popular
architectural style, and provides some real-life examples of how you can develop applications
using the microservices approach with IBM Bluemix. The source code for all of these
sample scenarios can be found on GitHub (https://github.com/).
The book also presents some case studies from IBM products. We explain the architectural
decisions made, our experiences, and lessons learned when redesigning these products
using the microservices approach.
Information technology (IT) professionals interested in learning about microservices and how
to develop or redesign an application in Bluemix using microservices can benefit from
this book.
Authors
This book was produced by a team of specialists from around the world working at the
International Technical Support Organization (ITSO), Austin Center.
Shahir Daya is an IBM Executive Architect in the IBM Global
Business Services (GBS) Global Cloud Center of
Competence. He is an IBM Senior Certified Architect and an
Open Group Distinguished Chief/Lead IT Architect. Shahir has
over 20 years at IBM, with the last 15 focused on application
architecture assignments. He has experience with complex,
high-volume transactional web applications and systems
integration. Shahir has led teams of practitioners to help IBM
and its clients with application architecture for several years.
His industry experience includes retail, banking, financial
services, public sector, and telecommunications. Shahir is
currently focused on cloud application development services,
and in particular platform as a service (PaaS), such as IBM
Bluemix; containerization technology, such as Docker; design
and development of Systems of Engagement (SOE); and
cloud-based IBM DevOps, including IBM Bluemix DevOps
Services.
xi
xii Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Preface
xiii
xiv Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Comments welcome
Your comments are important to us!
We want our books to be as helpful as possible. Send us your comments about this book or
other IBM Redbooks publications in one of the following ways:
Use the online Contact us review Redbooks form:
ibm.com/redbooks
Send your comments in an email:
[email protected]
Mail your comments:
IBM Corporation, International Technical Support Organization
Dept. HYTD Mail Station P099
2455 South Road
Poughkeepsie, NY 12601-5400
Preface
xv
xvi Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Part 1
Part
Introducing the
microservices
architectural style
In this part, we introduce the microservices architectural style, and show how you can develop
applications using this style in IBM Bluemix.
Providing a platform as a service (PaaS) environment as one of its run times, along with
containers and virtual machines (VMs), Bluemix leverages the Cloud Foundry project as one
of its open source technologies to accelerate new application development and integrated
application development and IT operations (DevOps) methodologies. Bluemix allows
separation of interface, implementation, and deployment. You can use Bluemix to create
applications in the microservices style and this section shows you how.
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 1.
Also, microservices can be developed in any programming language. They communicate with
each other using language-neutral application programming interfaces (APIs) such as
Representational State Transfer (REST). Microservices also have a bounded context. They
dont need to know anything about underlying implementation or architecture of other
microservices.
The following sections elaborate on the key aspects of this definition.
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
1.1.3 Language-neutral
Using the correct tool for the correct job is important. Microservices need to be built using the
programming language and technology that makes the most sense for the task at hand.
Microservices are composed together to form a complex application, and they do not need to
be written using the same programming language. In some cases Java might be the correct
language, and in others it might be Python, for example.
Communication with microservices is through language-neutral APIs, typically an Hypertext
Transfer Protocol (HTTP)-based resource API, such as REST. You should standardize on the
integration and not on the platform used by the microservice. Language-neutral makes it
easier to use existing skills or the most optimal language.
Monolithic architecture
Microservices architecture
Code
Understandability
Deployment
Language
Scaling
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
There have been some reasonable approaches to decompose applications into layered
architectures, such as model view controller (MVC), as shown in Figure 1-2. However,
applications are still clumsy with regards to level of business functions that each of the
applications are responsible for, therefore making them large and complex to manage.
Monolithic applications can also require longer peer code reviews. The lifespan for monolithic
applications tends to be longer than for a microservice, so there likely will be more developers
joining and leaving, resulting in higher support costs. This situation also causes inconsistent
coding practices and styles and inconsistent documentation methods. All of these elements
make maintenance and code reviews more time-consuming and difficult.
Microservice applications allow developers to more easily break down their work into smaller
independent teams, and to integrate that work as it is delivered and integrated.
In summary, microservices provide the following benefits for developers:
Enables you to avoid large code base, making it easier to maintain or add to features
Makes it easier to use existing skills, or the most optimal language
Improves deployment times and load times for IDE
Makes debugging easier
Enables teams to work more independently of each other
Simplifies tracking code dependencies
Enables complete ownership by a self-contained single team, from definition through
development, deployment, operations, and sunsetting
Makes it easier to scale bottlenecks
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Business owners want to delight their users. Microservices enable a better user experience
by enabling you to scale individual microservice to remove slow bottlenecks. Microservices
are designed to be resilient, which means improved service availability and an uninterrupted
user experience.
Business owners want to be able to offload work to third-party partners without the risk of
losing intellectual property. Microservices allow you to segment off work for non-core
business functions without disclosing the core services.
By adopting a microservices architectural style, it becomes quickly obvious where there is
duplication of services. Having a common platform for developing, building, running, and
managing your microservices enables you to more easily eliminate duplicate services, reduce
development expense, and lower operational management costs.
Figure 1-3 shows a microservices architecture with multiple languages and data store
technologies.
Application #1
User
Web Server
Application #3
Application #4
Application #2
Figure 1-3 Microservices architecture with multiple languages and data store technologies
10
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
It is important to be aware of when you are approaching monolith status and react before
that occurs.
11
12
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Although in both cases we are indeed talking about a set of services, the ambition of these
services is different. SOA attempts to put these services forward to anybody who wants to
use them. Microservices, alternatively, are created with a much more focused and limited goal
in mind, which is acting as a part of a single distributed system.
This distributed system is often created by breaking down a large monolithic application, and
the intent is that a collection of microservices continue to work together as a single
application. Typically, there is no ambition to serve multiple systems at the same time.
Unlike with SOA, microservices often exist implicitly. They are not discovered at run time, and
do not require mediation. They are well known to the consumers, and therefore do not require
service description. This does not imply that some kind of discovery is never present.
Some more sophisticated microservice systems might apply degrees of service discovery to
make them more flexible and more robust. The point is that such an architectural pattern is
not required. A microservice system where all microservices are aware of each other using
relatively simple configuration files is entirely possible, and can be an effective solution.
Teams can discover what microservices are available for them to use at development time
using a catalog, registry, or API management tools.
Nevertheless, SOA and microservice architecture share many principles, patterns, and a
programming model. After all, microservice architecture is a kind of SOA, at least in a
rudimentary way.
You can call it an extension or specialization of SOA, in which functional area boundaries are
used to define domain models and assign them to teams who can choose their own
development languages, frameworks, and deployment details. Similarly, service assembly,
orchestration, monitoring, and management is a real concern, and a requirement in
microservice systems in addition to more traditional SOA systems.
Unlike SOA, the business and technical motivations for microservices are different. Return on
investment (ROI) is driven by accelerated realization of benefits rather than overall business
transformation. Companies are less likely to invest in large and lengthy transformational
initiatives. Microservices enable incremental transformation using local optimization.
Based on this analysis, are we closer to pinpointing the differences between SOA and
microservices architecture? We could say that the key differences are those of ambition
and focus.
When we say ambition, we imply the set of problems that a particular approach attempts to
solve. By this criterion, microservices are intentionally trying to achieve less.
There is a good reason for that. Some of the real-world SOA systems have acquired a
reputation of complexity, and the need for very complex tooling and layers of abstraction in
order to even approach usability by humans. The most important reason for this complexity
was trying to achieve too much, and not engaging in SOA best practices to achieve that
recommended partitioning and complexity reduction.
Information: A good reference for SOA best practices is the following article,
Service-oriented modeling and architecture:
http://www.ibm.com/developerworks/library/ws-soa-design1/
You can also go to the following website for more information on SOA:
http://www-01.ibm.com/software/solutions/soa/
13
As a direct consequence of excessive scope, standards, and tooling that SOA had in the past,
microservice architecture is intentionally focused on solving a single problem. It is mostly
focused on incrementally evolving a large, monolithic application into a distributed system of
microservices that are easier to manage, evolve, and deploy using continuous integration
practices. You do not want any of the microservices that take part in the microservice system
to actually be used by another such system.
Although there is much emphasis on reuse, this reuse is not happening at a service level. All
microservices in a microservice system are primarily driven by one master application. These
microservices, if wanted, can then be reused by other existing or new applications to achieve
similar benefits, as described in 1.2, Benefits from microservices on page 6.
It is not hard to understand how this differentiation happened. SOA was designed with an
ambition to solve very complex enterprise architecture problems, with the goal of facilitating a
high level of reusability.
In contrast, microservices architecture was embraced by companies attempting to scale a
single web property to web scale levels, enable continuous evolution, make engineering
teams more efficient, and avoid technology lock-in. It is no surprise that, when approaching
the same general area of distributed systems composed of independent services, the
end-result is something quite different.
As a direct consequence of more focused and limited scope, and the emphasis on
incremental evolution from a traditional system to a microservice system, microservices are
increasingly attractive to businesses with significant infrastructure investment. The approach
promises less costly and more experimental, pay as you go transformation. In contrast,
traditional SOA typically required much more serious up-front financial and architectural
commitment.
To conclude, both SOA and microservices architecture are kinds of service architectures,
because both deal with distributed systems of services communicating over the network.
However, practical results are quite different, because the focus of SOA is on reusability and
discovery, where the focus of microservices is on replacing a single monolithic application
with a system that is easier to manage and incrementally evolve.
14
Case Study
Patterns
Benefits
e-commerce
Decompose a monolithic
application using Node.js
Financial
services
Incremental
re-platforming
Faster delivery
Reduce compute costs
Decompose monolithic
application using Node.js
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
15
The IT team chose Node.js as the main component of a new orchestration layer, as a proxy
for existing APIs.
In the new architecture, Node.js was used as a proxy and orchestration layer, where only
minor business logic resides. If this new layer can handle the changes required by the service
consumer, the logic would be coded in Node.js. If more involved transformations or
calculations were required, this proxy layer would pass the request to the existing API, until a
new service in Node.js could be created.
This approach allowed for the following benefits:
16
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
17
Application developers can work independently on their individual services, and are able to
quickly deploy fixes and enhancements, enabling a continuous delivery environment. The
elasticity provided by the Bluemix cloud services makes it possible for autoscaling to occur.
This scenario outlines the flexibility that exists when the application is designed using a
microservice architecture:
If the Online Store is getting a large volume of traffic, perhaps only the catalog application
needs to be scaled further.
If additional security is required to process customer orders, that portion of the application
can be updated to enforce more security checks without restricting the other components
of the application.
If a mobile front end needs to be developed, the RESTful communication between each
component makes it easy to add the new interface.
See Chapter 7, Scenario 2: Microservices built on Bluemix on page 123 for more details
about this application.
Flights
Customer account information
Authentication
Baggage services
When the monolithic version is converted to a microservices version of the Acme Air
application, a web front-end will run with an authentication microservice on a separate run
time. Communication between the microservices occurs using RESTful calls. Using the
Hystrix Dashboard, the separate services can be monitored.
Details of this application can be found in Chapter 8, Scenario 3: Modifying the Acme Air
application and adding fault tolerance capabilities on page 131.
18
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 2.
Elements of a microservices
architecture
In this chapter we introduce the key characteristics of a microservices architecture that make
it so appealing for modern application (app) and product development. We also go into a
detailed description of how to design microservices and microservices integration. Finally, we
give some thought to what the future of microservices architecture will be.
This chapter has the following sections:
19
2.1.1 Business-oriented
As a target system gets broken down into constituent services, there is a real risk that the
decomposition might be done along existing boundaries within the organization. This means
that there is potential for the system to be more fragile, because there are more independent
parts to manage, and parts that do not integrate well even though the resulting services can
communicate with each other.
Further, if the services that make up the system are not designed toward the correct goal,
they cannot be reused. Development and maintenance costs can also increase if the services
are designed along organizational or technology boundary lines.
It is critical to design microservices with the ultimate business objective in mind. This might
require teams across organizational boundaries to come together and design the services
jointly, rather than using microservices to route calls between teams.
Consider the scenario of old style service design shown in Figure 2-1.
Cu sto mer
Cu sto me r
Wirele ss Orde r
Man age ment
Wire less
Acti vati on
C ustomer
DB
POTS Orde r
Ma nag emen t
POTS
Acti vation
IPTV Orde r
Mana geme nt
Cu sto me r
DB
IPTV
Activa ti on
C ustomer
DB
In the previous scenario, the organizations communication structure has been mimicked
within the system design, and there are obvious flaws that have been introduced in perfectly
isolated services. The ordering system cannot scale, because each organization has its own
activation and order management system, each organization has its own view of the
customer, and no two parts of the organization have the same view of the customer.
The services designed in the previous scenario are also going to be affected by changes that
typically affect an organization, such as churn, mergers & acquisitions, and changes to the
network devices used to deliver the services. It wouldnt be unreasonable to expect that such
services are being measured by each department, with its own metrics of bugs, failures, and
performance. However, the order entry system as a whole is unable to serve the
organizations purpose.
20
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The microservice approach works well if designers and implementers of each part of the
organization communicate with each other to design the services jointly to service a common
business purpose. Figure 2-2 shows the application redesigned with the microservices
approach. Note that a similar structure would result from using an SOA approach as well.
Cu sto mer
Cu sto me r
C ustomer DB
Wirel ess
Activa ti on
IPTV
Activa ti on
POTS Orde r
Ma nag ement
Ord er Acti vation Ser vi ce
POTS
Activa ti on
In the previous scenario, cross-functional teams have come together to design a common
order entry service. When an order is received, it is stored in the database, providing a single
unified view of the customer. Upon order receipt, the order is sent to the orchestration service,
which calls each individual ordering system, as required. These calls then activate each part
of the order.
More important than the actual system architecture is the fact that services design does not
mimic organization, technological, or communication boundaries. The services can then
withstand changes to the organization (such as new products or services being added, or
new acquisitions), and changes to staffing. In addition, services are isolated in support of a
business function. This is an example of an embodiment of Conways Law.
21
Circuit breaker
The circuit breaker pattern is commonly used to ensure that when there is failure that the
failed service does not adversely affect the entire system. This would happen if the volume of
calls to the failed service was high, and for each call wed have to wait for a timeout to occur
before moving on. Making the call to the failed service and waiting would use resources that
would eventually render the overall system unstable.
The circuit breaker pattern behaves just like a circuit breaker in your home electrical system.
It trips to protect you. Calls to a microservice are wrapped in a circuit breaker object. When a
service fails, the circuit breaker object allows subsequent calls to the service until a particular
threshold of failed attempts is reached. At that point, the circuit breaker for that service trips,
and any further calls will be short-circuited and will not result in calls to the failed service. This
setup saves valuable resources and maintains the overall stability of the system.
Figure 2-3 shows the sequence diagram for the circuit breaker design pattern.
Circuit
Circuit Breaker
Breaker
Consumer
Microservice
timeout
timeout
call timeout
call timeou t
circuit trips
circuit open , qu ick return,
n o call to microse rvice
When the circuit breaker trips and the circuit is open, a fallback logic can be started instead.
The fallback logic typically does little or no processing, and returns a value. Fallback logic
must have little chance of failing, because it is running as a result of a failure to begin with.
22
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Bulkheads
A ships hull is composed of several individual watertight bulkheads. The reason for this is that
if one of the bulkheads gets damaged, that failure is limited to that bulkhead alone, as
opposed to taking down the entire ship.
This kind of a partitioning approach can be used in software as well, to isolate failure to small
portions of the system. The service boundary (that is, the microservice itself) serves as a
bulkhead to isolate any failures. Breaking out functionality (as we would also do in an SOA
architecture) into separate microservices serves to isolate the effect of failure in one
microservice.
The bulkhead pattern can also be applied within microservices themselves. As an example,
consider a thread pool being used to reach two existing systems. If one of the existing
systems started to experience a slow down and caused the thread pool to get exhausted,
access to the other existing system would also be affected. Having separate thread pools
would ensure that a slowdown in one existing system would exhaust only its own thread pool,
and not affect access to the other existing system.
See Figure 2-4 for an illustration of this separate thread pool usage.
User Action
User Action
Connection Pool
(shared)
Legacy
System 1
Legacy
System 2
Connection
Pool 1
Connection
Pool 2
Legacy
System 1
Legacy
System 2
Figure 2-4 Example using the bulkhead pattern: Using separate thread pools to isolate failure
23
Whatever the reason, careful thought must be given to sharing the database across
microservices. The pros and cons of doing so must be considered. Sharing a database does
violate some of the principles of a microservices-based architecture. For example, the context
is no longer bounded, where the two services sharing a database need to know about each
other, and changes in the shared database need to be coordinated between the two.
In general, the level of sharing between microservices should be limited as much as possible
to make the microservices as loosely coupled as possible.
2.1.4 Discoverability
As we described earlier, microservices architecture requires making services reliable and
fault tolerant. This in turn implies construction of microservices in such a way that, as the
underlying infrastructure is created and destroyed, the services can be reconfigured with the
location of the other services that they need to connect to.
With the use of cloud computing and containers for deployment of microservices, these
services need to be reconfigured dynamically. When the new service instance is created, the
rest of the network can quickly find it and start to communicate with it.
Most service discovery models rely on a registry service that all services explicitly register
with, and make calls to it later to communicate to the other services that they rely upon. There
are several open source registry services currently available that provide service discovery
capabilities, such as Zookeeper, Consul, and Eureka.
Remember that not all service discovery models rely on a registry service. For example,
Cloud Foundry, the open source platform as a service (PaaS) that Bluemix is built on, does
not rely on a registry service. Services in Cloud Foundry are advertised to the Cloud
Controller to make it aware of the existence of the service and its availability for provisioning.
Good discovery services are a rich source of metadata, which the registering services can
provide, and which can then be used by requesting services to make informed decisions
about how to use it. For example, requesting (or client) services can ask about whether a
service has any specific dependencies, their implications, and whether it is able to fulfil any
specific requirements. Some discovery services can also have load balancing capabilities.
24
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
One scenario could be that the clients of the system can make RESTful application
programming interface (API) calls, as depicted in Figure 2-5.
On the surface, this might seem desirable. However, there is likely a mismatch service
granularity. Some clients can be chatty; others can require many calls to get the necessary
data. Because the services would probably scale differently, there are other challenges to be
addressed such as handling of partial failures.
25
A better approach is for the clients to make a few requests, perhaps only one, using a
front-end such as an API Gateway, as shown in Figure 2-6.
The API Gateway sits between the clients and microservices, and provides APIs that are
tailored for the clients. The API Gateway is principally about hiding technological complexity
(for example, connectivity to a mainframe) versus interface complexity. Informally, an API
Gateway is a facade. However, a facade provides a uniform view of complex internals to
external clients, where an API Gateway provides a uniform view of external resources to the
internals of an application.
Much like the facade design pattern, the API Gateway provides a simplified interface to the
clients, making the services easier to use, understand, and test. This is because it can
provide different levels of granularity to desktop and browser clients. The API Gateway might
provide coarse-grained APIs to mobile clients, and fine-grained APIs to desktop clients that
might use a high performance network.
In this scenario, the API Gateway reduces chattiness by enabling the clients to collapse
multiple requests into a single request optimized for a given client (such as the mobile client).
The benefit is that the device then experiences the consequences of network latency once,
and leverages the low latency connectivity and more powerful hardware server-side.
The following sections describe other considerations for implementing communications
between services.
26
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
27
The following list describes some considerations for dealing with complexity introduced by the
use of microservices:
Testing
Monitoring
DevOps
Polyglot programming
Idiomatic use of microservices also means that the resulting system
would be polyglot, which presents a unique challenge of maintaining a
hyper-polyglot system. As a result, the database administrator (DBA)
now needs to be replaced with programmers who can deploy, run, and
optimize noSQL products.
Maintaining a pipeline of skilled developers, tinkerers, and researchers
is as critical as maintaining the DevOps pipeline to ensure that there
are enough skilled developers to maintain the platform, and to improve
system design as new advancements are made. Note that most
organizations have a short list of programming languages that they
use. There are benefits to that from a code and skills reuse standpoint.
28
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Because a microservice is small and usually designed, developed, and maintained by a small
two-pizza team, it is typical to find microservices that get entirely rewritten, as opposed to
being upgraded or maintained. A common trade-off is in how small you make your
microservice. The more microservices you have in the decomposition of a monolithic
application, the smaller each is. And the smaller each is, the lower the risk in
deploying/releasing changes to it.
However, the smaller each microservice is, the more likely it is that a typical application
update will require more microservices to be deployed, therefore increasing the risk. The
principles of microservices, such as independent deployability and loose coupling, need to be
considered when determining what capability becomes a microservice. There is a more
detailed description of this in the next section.
Hills
Hills Playback
Scenario
User story
Epics
Sponsor users
Identifying microservices opportunities
Hills
Hills provide business goal for your release timeline. A Hill defines the who, what, and how of
what you want to accomplish. A team typically identifies three Hills per project, and a
technical foundation. Hills provide the commanders intent to allow teams to use their own
discretion on how to interpret and implement a solution that provides for a good user
experience. Hills definition should be targeted at a user and measurable. Avoid using vague
or non-quantifiable adjectives. Example 2-1 shows a sample Hill.
Example 2-1 Sample Hill
Allow a developer to learn about iOS Bluemix Solution and deploy an application
within 10 minutes.
29
Hills Playback
Hills playback provides a summary of what the team will target. Hills Playback sets the scope
for a specific release time period. Playback 0 is when the team has completed sizings, and
commits to the business sponsors regarding the outcomes that it wants to achieve. Playbacks
are performed weekly with participation from the cross-functional teams, and the sponsor
users who try to perform the Hills. Figure 2-7 shows a Hills Playback timeline.
Scenario
A scenario is a single workflow through an experience, and it sets the story and context used
in Hills Playbacks. Large scenarios can be further decomposed into scenes and product user
stories. Scenarios capture the as is scenario and the to be improved scenario.
User story
A user story is a self-contained, codeable requirement that can be developed in one or two
days, expressed in terms of user experience, for example: As a developer, I want to find
samples and quickly deploy them on Bluemix so I can try them.
Epics
Epics group stories into a form that can be reused multiple times across the scenario, so that
stories arent repeated.
Sponsor users
Sponsor users are users that are engaged throughout the project to represent target
personas for a project. They are expected to lead or participate in Playbacks. Sponsor users
can be clients who use the applications that include microservices. They can also be internal
developers who use microservice onboarding tools that you are developing in support of your
DevOps release process.
30
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
31
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Note that, in a well-designed system fronted with a reverse proxy, this reorganization can be
run without any disruption. Where a single microservice was serving two URL paths, two new
microservices can serve one path each. The moral is that microservice system design is an
ongoing story. It is not something that must be done all at once, immediately.
2.3.1 REST
REST is an architectural style for networked applications, primarily used to build web services
that are lightweight, maintainable, and scalable. A service based on REST is called a
RESTful service. REST is not dependent on any protocol, but almost every RESTful service
uses HTTP as its underlying protocol.
REST is often used for web applications as a way to allow resources to communicate by
exchanging information. If you consider the web as an application platform, REST enables
you to have applications that are loosely coupled, can be scaled and provide functionality
across services.
Over the past decade, REST has emerged as a predominant web service design model, and
almost every major development language includes frameworks for building RESTful web
services. The REST APIs use HTTP verbs to act on a resource. The API establishes a
mapping between CREATE, READ, UPDATE, and DELETE operations, and the corresponding POST,
GET, PUT, and DELETE HTTP actions.
The RESTful interface focuses on the components roles and resources, and ignores their
internal implementation details. Requests are sent to a server that is component-aware,
which masks the intricate details from the users. The interactions must be stateless, because
the requests might travel between layered intermediaries between the original client agent
and the server.
These intermediaries might be proxies or gateways, and sometimes cache the information. A
constraint exists with REST that requires stateless communication. Every request should
contain all of the information that is required to interpret that request. This increases the
visibility, reliability, and scalability, but also decreases performance because of the larger
messages required for stateless communication.
Figure 2-8 is a simple overview of REST architecture showing how intermediary proxies and
gateways, and the REST server, can cache information.
Cache
Proxies
REST Client
Cache
Cache
Gateways
REST Server
33
As shown in Figure 2-8 on page 33, one or more proxies or gateways can exist between the
client agent that is requesting the information and the server. The responses must have a
mechanism to define themselves as cacheable or non-cacheable. Well-managed caching
improves the scalability and performance of a RESTful service.
Because REST is designed around a request/response model, if the wanted response is not
available, the application would need to do the call again later. In some cases, this could lead
to frequent polling by the application.
2.3.2 Messaging
In todays cloud environment it is desirable to implement a microservices architecture for
many scenarios. Moving away from monolithic applications to a coalition of smaller
collaborating applications requires a way for these small discrete microservices to
communicate with each other. This is where messaging can help. By decomposing your
application, actually breaking it down to components, it keeps the services modular and
scalable so that they are easier to debug.
Messaging is a critical component to the application development world, enabling developers
to break down an application into its components, and loosely couple them together.
Messaging supports asynchronous coupling between the components, with messages sent
using message queues or topics.
A messaging publish/subscribe pattern reduces on unnecessary linkages and network traffic
between applications. Rather than having to use the frequent REST polling calls, the
application can sit idly until the message is published to all of the interested (subscribed)
parties. At that point, the subscribed application receives the message. In essence, rather
than using a REST are we there yet call, the subscriber gets a shoulder tap to indicate that
the message they want is available.
In a publish/subscribe topology, the publishing application sends a message to a destination,
often a topic string. The ability of the publisher to put the message is not dependent on
subscriber applications being accessible. The message broker acts as an intermediary, and is
responsible for delivering the message to every subscriber.
At any point in time, a subscriber could be unavailable. Message brokers can retain the
message until a subscriber is able to consume it. The level of message delivery assurance is
handled by the quality of service (QoS), such as at most once or at least once.
An important advantage of using message queues in your project is feature growth. What
begins as a simple application can easily grow into a massive app with a barrage of new
features. A fairly straightforward app gets more complex as new requirements arrive, and you
need a simple way to add those features with the least disruption to the current application.
Because messaging helps decouple the components of an application, a new application
feature can be written to use messaging as a means of communicating with the existing
application, and not require changes or downtime for the main application when the new
feature is deployed.
Alternatively, you might have a large monolithic application that is part of your systems of
record, and you want to extend your enterprise and focus on integrating systems of
engagement. Messaging can be instrumental in integrating the existing systems with new
front-end features, by enabling communication between the two without the need for both
applications to be running on the same platform or written in the same language.
34
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Many existing systems might already employ some type of enterprise messaging system.
Therefore, an optimal design for a new microservice would be one that employs messaging
that can be tied into the existing system and communicate with its existing enterprise
messaging system.
Some common implementation scenarios for using messaging would be event notification
and worker offload, as shown in Figure 2-9.
Use Cases
Worker Offload
Event Driven
35
For example, a stock broker application, as shown in Figure 2-10, publishes price updates to
a set of trading applications in an event notification scenario. The messaging broker
manages the storage and distribution of the messages to each interested application. The
subscriber does not have to send individual requests, it just subscribes for the topics that it
wants, and when those messages are published, they are delivered to the subscriber.
Receiver Applications
Stock Price
Changed
Sender Application
Publis her
Messaging
Stock Price
Changed
Subscriber
Subscriber
Subscriber
Stock Price
Changed
Figure 2-10 Event notification for stock price
Another example of messaging would be a web application that needs to process work while
being responsive to the front-end users. When an application has intensive work to be done, it
can be offloaded and distributed among worker processes to be performed asynchronously.
Several instances of a back-end worker application could exist, enabling the web application
to send a work request for processing by one of several worker application instances.
Messaging helps implement a worker offload scenario in this case, distributing the work
among the worker applications and, if the load increases, additional worker applications can
be created without the need to alter the web application.
Messaging helps make applications more flexible by enabling the separate microservices to
process asynchronously. Incorporated a messaging service in your microservices design can
help ensure that applications remain responsive even when another system is not available or
responding fast enough.
The IBM MQ Light service in Bluemix is a fully managed cloud service, so all of the
operations activities, such as maintenance, availability, and upgrades, are part of the Bluemix
service. IBM MQ Light offers different qualities of service to ensure either at most once
message delivery or at least once message delivery.
The acknowledgment of message delivery, and high-availability (HA) deployment of IBM MQ
Light in Bluemix, are critical in resilient systems design. See Chapter 4, Developing
microservices in Bluemix on page 57, and Chapter 7, Scenario 2: Microservices built on
Bluemix on page 123, for more information about IBM MQ Light, which is available as a
Bluemix service.
36
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
37
38
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 3.
39
40
Requirements
Testing
Deployment
Operational monitoring of the service
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Automation on steroids is the theme of DevOps. As depicted in Figure 3-1, every traditional
hand off point is automated in a DevOps approach. Automation begins from provisioning of
the infrastructure and configuration of the platform for the workloads. This is followed by the
automation of application deployment, database changes, and other application-related
configurations.
Finally, maximum benefits in a DevOps approach are gained through test automation in the
form of unit tests, system integration tests, and user acceptance tests. Because
microservices represent small, composable business functions, the level of automation
possible through a DevOps approach aligns perfectly for its development lifecycle.
Plan
D eve lop
Tes t
Re le ase
Req uirements
Code
Uni t, SI T, UAT
P roducti on
Custom ers
The aspect of standardization in DevOps can easily be confused with the flexibility that a
microservices architecture provides with regards to technology and data store stack. In a
DevOps world, standardization to reduce risk refers to the following factors:
Using standard platforms
Reliable and repeatable process
High level of confidence by the time you are ready to release
41
Frequent releases keep applications relevant to business needs and priorities. Smaller
releases means lesser code changes, and that helps reduce risk significantly. With smaller
release cycles, it is also easier to detect bugs much earlier in the development lifecycle. Quick
feedback from the user base also supports code adaptability. All of these characteristics of a
DevOps approach augur well for microservices development.
Several common pain points that affect a traditional software delivery, as depicted in
Figure 3-2, are mitigated to a large extent with the use of a DevOps approach for
microservices development.
A pprovals / Check Point s
Platform
1
Develop
2
Build
Test
Pro d
Stage
6 9
10
I dea
7
8
1 Long lead times for platform availability (manual
IBM DevOps framework addresses continuous delivery through a series of continuous steps,
as shown in Figure 3-3.
C ontin uou s
Bu sine ss Pl ann ing
Ope rate
Co ntinu ous
Mon itorin g
Collaborative
Development
Steer
C ontin uou s
Customer Fee dba ck
& Optimi zation
D evOps
Continuous
Feedback
De velo p/
Test
De plo y
C on ti nuo us
Te sti ng
42
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
IBM Bluemix DevOps Services is a software as a service (SaaS) on the cloud that supports
continuous delivery. With IBM Bluemix DevOps Services, you can develop, track, plan, and
deploy software in one place. From your projects, you can access everything that you need to
build all types of applications (apps). To simplify team work, use the collaboration tools. After
you build an app, you can deploy it to the IBM Bluemix cloud platform. You can go from source
code to a running app in minutes.
IBM Bluemix DevOps Services provide the following capabilities:
The following sections describe these capabilities, and explain how they are useful in context
of microservices.
Continuous business planning employs lean principles to start small by identifying the
outcomes and resources needed to test the business vision and value, to adapt and adjust
continually, measure actual progress, learn what customers really want, shift direction with
agility, and update the plan.
Continuous business planning has the following benefits:
Some of the most commonly used industry tools and offerings for continuous business
planning are described in the following list:
43
Bringing together customer and IBM team stakeholders toward a partnered goal
Focused on delivering a tangible and functional business outcome
Working within a time-boxed scope
Using common tools and process platform (customer, traditional, or IBM Cloud)
The following list describes some of the most commonly used industry tools and offerings for
continuous integration and collaborative development:
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The following list describes some of the most commonly used industry tools and offerings for
continuous testing:
45
46
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
47
Silo-driven development is often frowned upon in the architecture community. However, large
enterprises can lack the agility and executive support to spin off innovative projects to develop
proof points of a certain technology that might drive business value. Therein lies the
advantages of what some call skunk work. Although microservices architecture is not a
throwaway type of work, it does have the advantage of realizing business value quickly, or
failing quickly, so other aspects can be considered as part of a solution.
For these reasons, a siloed approach can have a reason to exist. There are arguments in the
industry that often describe silos as logical pieces of a larger linear process that ultimately
have a common goal of solving a business problem. But the larger argument for such a
method is budgetary constraints. Enterprises seldom allocate funding and time to fully
understand a specific business problem well enough to deliver a solution as a service.
Decentralization of governance can help mitigate such situations. The enterprise has time
constraints on full-scope product deployment, and also has limited budgets on incremental
development and delivery. The key value with decentralized governance is that a proof point
can be quickly established, with some knowledge of return on investment (ROI) and a time
frame for that, without incurring extensive risks regarding time and money.
One of the ramifications of decentralized governance is the concept of build it and run it. This
is a disruptive model to a traditional organization built on functional teams not based on
business domains. A microservice team is responsible for all aspects of the service delivery,
from build to run to fix. From an architectural thinking perspective, it is not enough to design
for functional delivery.
In addition, non-functional and support models become increasingly important. The same
team that designed a microservice can end up being the one answering support calls over the
weekend. This is clearly an organizational transformation issue, as illustrated in 3.3.2,
Enterprise transformation for microservices on page 50.
48
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Application #1
User
Web Server
Application #3
Application #4
Application #2
49
Design Thinking
Fault Tolerance, Central Logging, Event Dri ven
Roles Redefinition
DevOps Engineers , Self Servi ce, SoE Designers
Automate Development
Common Services
Skills Augmentation
Microservices Governance
DevOps Governance
A rchitectural Transformation
Process Transformation
Organizational Governance
Ski lls Asses sment, 360 Feedb ack
Organizational Transformation
Architectural transformation begins with identifying and decomposing business functions into
independently manageable units or workloads. It is certainly a disruption in traditional
architectural thinking methods, and it requires a few iterations of design planning to get
it correct.
As a growing number of self-contained composable services are identified, there is also an
element of service management complexity due to rapidly increasing volumes of workloads to
manage. Source code management, deployment, and release managements and testing
strategies, all become slightly more complicated than with a monolith.
This is where the process transformation of DevOps becomes essential for a microservices
architecture to have any degree of success. From automation of environment provisioning to
automation of deployments and releases, all play a key part in reducing manual resource
demands, number of errors, and a truly agile way to deliver software. With the level of
automation involved, there is also an infusion of several new tools and scripting languages
that come into play.
Just as DevOps transformation is a key driver for microservices architecture to succeed, an
organizational transformation is essential for the process transformation to succeed. With
DevOps, new job roles are created, and existing ones are redefined. Skills training and a new
way of thinking become crucial for success. With large enterprises, this means that there
might be new partnerships with vendors and service providers to supplement skills.
Because microservices teams are designed to align with its architecture, teams will also be
self-contained. The concept of build it, run it is often talked about with microservices. There
is always resistance to change with large enterprises, so executive commitment and coaching
becomes critical during transformation.
50
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Unit testing
Integration testing
Component testing
Contract testing
End-to-end testing
Performance testing
Unit testing
A unit test in microservices is the same as in other systems, and can be understood as
running the smallest piece of testable software to determine whether it behaves as expected.
Although there is no exact definition of how big the testable piece against which we run the
unit testing should be, a typical unit to be tested should have some of the following common
elements:
The unit is a low-level piece of the system, and focuses on a specific small scope of the
system. It might be a class of code, a single function, or a group of functions.
Testing against the unit should be significantly faster than other kinds of tests.
Unit test script is usually written by the developers who built the code that is under test.
This testing is where we hope to detect most of the bugs in the system, and it is the most
frequently run testing compared to other kinds of tests. The primary goal of unit testing is to
give us fast feedback about whether the implemented piece of code is good in isolation.
This test is also critical in the code refactoring activities, where small-scoped tests can prove
timely to help ensure the quality of the code restructuring as you proceed with development.
Unit testing is also a principal tool in a test-driven development approach, helping to obtain
fast feedback about the system we build from the beginning.
51
Integration testing
Integration testing is a testing method that collects relevant modules together, and verifies
that they collaborate as expected. Integration testing accomplishes this by exercising
communication paths among the relevant modules to detect any incorrect assumptions that
each module has about how to interact with other modules under test.
In microservice architectures, this testing is typically used to verify interactions between the
layers of integration code, and any external components that they integrate to. The external
components might be data stores, other microservices, and so on.
The integration test against data stores external components, or persistence integration test,
ensures that the schema used by the code matches the real one in the external data store. In
many cases, the object-relational mapping technique might be used to convert data. This
might create more complications in the persistence integration test, which needs to be
structured to consider the dependency of the test with the configuration on the tool to ensure
that the data makes a full round trip.
Also, data stores can exist across a network partition that might cause timeouts and network
failures. Integration tests should attempt to verify that the integration modules handle these
failures gracefully.
Another important external integration test is the test against communication between two
microservices. Very often, a proxy component is used to encapsulate messages passing
between two remote services, marshalling requests and responses from and to the modules
that actually process the request. The proxy is usually accompanied by a client that
understands the underlying protocol to handle the request-response cycle.
The integration testing in this case needs to detect any protocol-level errors, such as incorrect
Secure Sockets Layer (SSL) handling, missing HTTP headers, or mismatches of
request-response body. Special case error handling should also be tested to ensure that the
service and the client employed respond as intended in exceptional circumstances.
Because the integration testing relies on a certain set of data being available, one technique
that can be used is that both parties agree on a fixed set of harmless representative data that
is guaranteed to be available as needed.
Sometimes it is difficult to trigger abnormal behaviors, such as a slow response from an
external component. In this case, the test might use a stub version of the external component
as a test harness that can be configured to fail at will.
Component testing
A component is part of a larger system that is encapsulated, coherent, and independently
replaceable to other parts. A component test limits the scope of the exercised software to a
portion of the system under test, manipulating the system through internal code interfaces,
and using techniques to isolate the code under test from other components.
By limiting the testing scope within a single component, and isolating it from its peers, you can
eliminate noise introduced by any possible complex behavior of the external components
that would affect the test result. This enables you to focus thoroughly on testing the behavior
encapsulated by that particular component. That isolating also results in a faster test, and
provides a controlled testing environment where error cases can be retriggered at will.
In a microservice architecture, the components are considered the services themselves. The
isolation for testing a service is usually achieved by representing the associated external
collaborators with their simulators (for example, fake, spies, dummy, and stubs), through a set
of internal API endpoints to probe the service.
52
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The following list includes two common component testing options in microservices
architecture:
In-process component tests. Allow comprehensive testing while minimizing moving parts.
This test creates a full in-memory microservice, with in-memory service simulators and
data stores, that ultimately helps to eliminate any network traffic, lead to faster test
execution time, and minimize the number of moving parts to reduce build complexity. The
downside of this technique is that the work products under test must be altered
accordingly for testing purposes.
Out-of-process component tests. Exercise the fully deployed work products.
This test is against a microservice deployed as a separate process. It enables exercising
for more layers and integration points. The interactions are through real network calls so
that there is no need to alter the component under test with test-specific logic. This
approach pushes the complexity into the test harness, which is responsible for starting
and stopping external stubs, coordinating network ports, and configuration.
The test execution time consequently increases due to the use of the real data store and
network interaction. However, this approach is more appropriate for testing microservices,
which have a complex integration, persistence, or startup logic.
Contract testing
A contract is conceptually a proliferation of interfaces between two services. A contract test is
a test at the boundary of an external service to verify that it meets the expectation of the
contract formed between the service and its consuming services. The contract consists of
expected requirements for input and output data structures, performance, concurrency
characteristics, and so on. A component can change over time, and it is fundamental that the
contracts of its consumers continue to be satisfied after the changes.
In microservice architecture, the contract is fulfilled through a set of APIs exposed by each
service. The owner of its consuming services is responsible for writing an independent test
suite, which verifies only the aspects of the producing service that are in the contract. That
contract test suite should be packaged and runnable in the build pipelines for the producing
services, so that the owner of the producing service might be informed of the effect of the
changes on their consumers in a timely manner.
The overall contract can be defined by summing up all of the consumer contract tests. The
consumer-driven contracts form a discussion point with the service owner, based on which
the test can be automated to provide an indication of the readiness of the API.
Several tools exist to help writing contract tests, such as Pact and Pacto. You can find more
information about these tools on the following websites:
Pact: https://github.com/realestate-com-au/pact
Pacto: https://github.com/thoughtworks/pacto
End-to-end testing
An end-to-end test is a test verifying that the system as a whole meets business requirements
and achieves its goals. The test accomplishes this by exercising the entire system, from
end-to-end.
Because of the naturally autonomous nature of a microservice architecture-powered system,
it usually has more moving parts for the same behavior as other systems. End-to-end tests
can help to cover the gaps among the services. This test provides additional confidence in the
correctness of messages passing between the services. The test also ensures that any extra
network infrastructure, such as firewalls, proxies, and load-balancers, are properly
configured, as well.
Chapter 3. Microservices and DevOps
53
Over time, a microservice architecture-powered system usually evolves, with services being
merged or split to address the business problem domain, that also evolves. End-to-end tests
also add value by ensuring that the business functions provided by that kind of system remain
intact during such possible large-scale architectural refactorings.
The test boundary for end-to-end tests is much larger than for other types of tests, because
the goal is to test the behavior of the fully integrated system. End-to-end testing interacts at
the most coarse granularity possible, and is the most challenging testing type to build and
maintain. As the test scope increases, so does the number of moving parts, which can
introduce test failures. These problems do not necessarily show that the functionality under
test is broken, but rather that some other problems have occurred.
Ideally, you can manage all of the external services of the system to be included in your
end-to-end testing. However, in many cases, the services are managed services from a third
party, which limits you from building a side-effect-free end-to-end test suite. The results are
that the test fails for the factors that are out of your control. In such cases, it can be more
beneficial to stub the external services and sacrifice some end-to-end confidence, but in
return gain stability in the execution of the test suite.
Due to the additional complexity of writing end-to-end tests, the test team should selectively
decide how extensively this test should be used in their testing strategy. The following list
includes some guidelines to make an effective end-to-end test suite:
Make the end-to-end test as small as possible. The main goal of performing end-to-end
testing is to make sure that all services that make up the system instrumented work well
together as a whole. An adequate level of confidence in the behavior of the system might
be more beneficially achieved by focusing on other types of tests rather than putting too
much effort into end-to-end testing.
Avoid dependency on pre-existing data. Because data is most likely going to be changed
and accumulated as the testing goes on, relying on a set of pre-existing data might cause
nonsense failures. These breakdowns are not an indication of the failure of the system
under test. A solution for this is to automate the data management so that the system can
initialize its data upon the actual test execution.
Mimic production environment in a fully automated manner. The deployment complexity of
a microservice architecture system might result in many difficulties in replicating the
environment for an end-to-end test. One solution might be using an infrastructure-as-code
(IaaS) approach by using some automation frameworks, such as Chef or Puppet, which
might help build environments as needed, in a reproducible manner.
Make the test consumer-driven. Model the tests around the consumers of the service in
terms of their personas, in addition to the patterns that they navigate through the system
under test. You might even test in production with feature switches.
Performance testing
Performance tests should run against service-to-service calls, and against a particular
service in isolation, to track microservices individually and keep performance issues under
control. Usually, a good way to start is with identifying major journeys in the system, put each
of the services and also all services under gradually increasing numbers of requests.
This way we can track how the latency of the calls varies through increasing load. Ideally, the
component or system under performance test should be placed into an environment that is as
similar to production as possible. In this way, the test result might be more indicative of what
the production environment would look like in a similar situation.
54
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Performance testing also should be done jointly with monitoring the real system performance.
It should ideally use same tools as the ones in production for visualizing system behavior,
because it might make it easier to compare the two. A comprehensive centralized logging tool
is a good example for that with which we can see precisely how the microservices are acting.
The following list describes some outlines to consider for completing performance testing
against a microservice system:
Use as much real data as possible.
Load the test with real volume similar to that expected on production.
Push the test through in as close to production conditions as possible.
Do the performance test early, and regularly, not just once immediately before moving to
production.
Consider continuing to gain performance insights and monitoring performance in
production as appropriate.
55
56
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 4.
Developing microservices in
Bluemix
This chapter describes building a microservice application on IBM Bluemix. Using a
well-rounded platform for building, running, and managing your applications (apps) can
alleviate much of the operational, networking, and other infrastructural resource costs of the
microservice architecture.
A well-rounded platform also enables continuous delivery capabilities for the entire
application lifecycle management (ALM). Bluemix aims to simplify software development and
management on the cloud by providing a complete set of flexible run times, integrated
services, and DevOps tools that include development, testing, scaling, monitoring,
deployment, and logging.
The aim of this chapter is to first provide an introduction to Bluemix, describe developing and
deploying microservices using Bluemix DevOps capabilities, and outline some considerations
when leveraging Bluemix for microservices.
This chapter has the following sections:
4.1, Bluemix introduction on page 58
4.2, Developing microservices using Bluemix DevOps on page 68
4.3, Deployment, testing, monitoring, and scaling services in Bluemix DevOps on
page 76
4.4, Communication, session persistence, and logging in Bluemix on page 81
4.5, Considerations and opportunities on page 86
57
Bluemix encourages polyglot practices, and enables you to develop different services using
different languages and run times.
Polyglot programming: A polyglot is a computer program written in multiple programming
languages, which performs the same operations or output independent of the
programming language used to compile or interpret it.
You can also employ polyglot persistence to store data in different data storage technologies,
depending upon the varying needs of your applications. Through composition of these
consumable services and run times, Bluemix enables rapid development of your application.
Bluemix also provides tools for testing and rapid deployment of your application. When
deployed, there are more tools for monitoring, logging, and analytics, in addition to the ability
to easily scale up or down based on changes in the usage or load of your application. Bluemix
provides a platform for application development, deployment, DevOps, and monitoring. We
describe specifics of the Bluemix experience in the following section.
58
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Available Options
Access model
Compute infrastructure
Virtual Images
Cloud Foundry Applications
Docker Containers
Public
Bluemix is offered as a PaaS environment leveraging SoftLayer virtual servers to anyone
over the Internet. This public availability means that to become quickly productive with
Bluemix, a developer only needs to make an account and start developing and deploying
applications.
Figure 4-2 on page 60 shows the basic flow of how Bluemix manages the deployment of
applications for public platforms. When an application is developed and deployed, the
execution environment for that application is isolated from the execution environment of other
applications, even though that application might be running in the same data center as
other applications.
59
Dedicated
Bluemix Dedicated is your own exclusive SoftLayer environment thats securely connected to
both the public Bluemix and your own network. Bluemix Dedicated is connected to your
network through a virtual private network (VPN) or a direct network connection. Your
single-tenant hardware can be set up in any SoftLayer data center around the world.
IBM manages the dedicated platform and dedicated services, so that you can focus on
building custom applications. In addition, IBM performs all maintenance to dedicated
instances during a maintenance window selected by you. IBM has several services that are
available in your dedicated environment, but you can connect to public services as well. All
run times are available in the dedicated environment.
All dedicated deployments of Bluemix include the following benefits and features:
Local
Bluemix Local is geared more toward enterprises that want to have their own environments,
and brings all the advantages of a PaaS into their private world and own data center. It is
delivered as a fully managed service in your own data center, and brings cloud agility and
Bluemix features to even the most sensitive workloads. Bluemix Local sits either on
OpenStack or VMWare driven infrastructure, or on a Bluemix appliance. It also features a
syndicated catalog from the public Bluemix offering so that you can easily locate apps and
services based on their specific business or technical requirements.
60
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Regions
A Bluemix region is a defined geographical territory that you can deploy your apps to. You can
create apps and service instances in different regions with the same Bluemix infrastructure
for application management, and the same usage details view for billing. You can select the
region that is nearest to your customers, and deploy your apps to this region to get low
application latency. You can also select the region where you want to keep the application
data to address security issues.
When you build apps in multiple regions, if one region goes down, the apps that are in the
other regions continue to run. Your resource allowance is the same for each region that you
use. You can switch between different regions to work with the spaces in that region.
Figure 4-3 illustrates all three deployment models of Bluemix.
2 | D e d i c a te d
E ve ry t h in g is d e d ic a t e d
and c onnec ted to y ou
a g ilit y o f p u b lic c lo u d , y e t
fe e ls lik e h o m e .
1 | P u b lic
M a x im iz e o n c lo u d
e c o n o m ic s a n d a g ilit y .
S e a m l e ss Ex p e ri e n c e
R e g a rd le s s o f w h ic h
c o m b in a t io n y o u c h o o s e ,
y o u c a n e x p e c t a s in g le ,
s e a m le s s e x p e rie n c e .
3 | NEW : L o ca l
B e h in d t h e fire w a ll fo r t h e
m o s t s e n s it ive w o rk lo a d s .
Cloud Foundry
IBM Bluemix is based on Cloud Foundry, which is an open PaaS. In this PaaS model, you can
focus exclusively on writing your code. You can leave aspects of running your application
code to Bluemix, because all infrastructure, including the application servers, are provided by
Bluemix. Bluemix takes care of the management and maintenance of all of the infrastructure
and run time that powers your application.
This enables developers to build applications rapidly in local integrated development
environments (IDEs) and push the apps to the cloud. This ease of use, however, comes at the
expense of having less control over the infrastructure, which is desirable in certain scenarios.
61
Containers
With this option, you run your application code in a container that is based on the popular
Docker containers. Different from the previous Cloud Foundry model, you not only must
provide the applications, but also the application servers or run times, which are both included
in the containers.
This comes with the benefit that you can port your applications more easily because you can
run these containers locally, on-premises environments, and on cloud. The main
disadvantage is that there can be some resource use involved with building and managing
these containers. However, there are many images available that are provided by both IBM
Bluemix (images for Liberty and Node.js) and public Docker Hub.
Note: With this option, you run pure Docker containers in a hosted environment on
Bluemix. These are the same containers that run on-premises in a simple Docker
environment, or in any other cloud-provider offering Docker services.
Virtual machines
In this option, you run your app code on your own VM with its own operating system (OS).
Therefore, you are not only responsible for providing the application servers and run times,
but also the operating system, so you have even more resources to use with building and
management of the images relative to the previous options. There are public virtual images
available, and the Bluemix virtual machines infrastructure does give you the ability to create
and manage virtual machine groups on the IBM public cloud that makes management easier.
You can also create and manage VM groups on your private IBM clouds that youve chosen to
make available to Bluemix users, in addition to the ability to connect to your on-premises
infrastructure through guided experience. You can deploy and manage your VMs by using
either the Bluemix user interface (UI), or the clouds OpenStack application programming
interfaces (APIs).
62
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
IBM Cloud Integration is another service that aids in building hybrid environments by exposing
back-end systems of record as Representational State Transfer (REST) APIs. This enables
you to provide a standard way of exposing your systems of record data in a standard,
easy-to-use format. You can selectively show only those schemas and tables that you want.
See the diagram in Figure 4-5 for a general flow.
Applications
In Bluemix, an application, or app, represents the artifact that a developer is building.
Mobile apps
Mobile client apps can use Mobile services that are provided in the Bluemix Catalog, or that
are already deployed to and running in Bluemix. These services typically act in concert, and
represent the back-end projection of that application. Bluemix can then run and manage
these microservices.
Web apps
Web apps consist of all the code that is required to be run or referenced at run time. Web
apps are uploaded to Bluemix to host the application. For languages such as Java, where the
source code is compiled into runtime binary files, only the binary files are required to be
uploaded. When building microservices, each microservice can be deployed as a Bluemix
web application, and can communicate with each other using Hypertext Transfer Protocol
(HTTP) or one of the provided services.
63
Services
In the Bluemix and Cloud Foundry terminology, a service is essentially any resource that can
help a Bluemix user (developer or operator) develop and run their application. Bluemix
services provide functionality that is ready-for-use by the apps running code. Example
services provided by Bluemix include database, monitoring, caching messaging, push
notifications for mobile apps, and elastic caching for web apps.
Bluemix stands out from the rest of the competition by providing a massive catalog of these
pluggable services, ready to be immediately provisioned and used by your application. The
Bluemix console displays all the available services in one single catalog view, as shown in
Figure 4-6.
Some of the services have a different flow, but for most of them, you simply select a service
and click Create. Within moments, Bluemix provisions your own instance of the service and
provides the credentials for any application that you bind the service to.
Many powerful IBM products like IBM DB2 and Elastic Caching are offered as a service for
quick consumption, with no setup. The catalog is populated with not only IBM products, but
also third-party and community services like MongoDB and Twillio.
Many options in the catalog: This type of catalog creates a flexible environment that
developers love. For example, at the time of this writing there are over 100 services and 12
different types of data management services to choose from.
64
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
You can create your own services in Bluemix. These services can vary in complexity. They
can be simple utilities, such as the functions you might see in a runtime library. Alternatively,
they can be complex business logic that you might see in a business process modeling
service or a database.
Bluemix simplifies the use of services by provisioning new instances of the service, and
binding those service instances to your application. The management of the service is
handled automatically by Bluemix. For all available services in Bluemix, see the catalog in the
Bluemix user interface:
https://console.ng.bluemix.net/?ace_base=true/#/store
Read more about the using services in your applications or creating services in the
CloudFoundry documentation. Most of these capabilities are also available in Bluemix:
http://docs.cloudfoundry.org/devguide/services/
If you want to offer your own service in the IBM Bluemix Catalog as a third-party service,
consider joining the IBM marketplace:
http://www.ibm.com/cloud-computing/us/en/partner-landing.html
This site shows you how to work with IBM to create and start the Service Broker API calls to
enable you to have your service listed in the IBM Bluemix Catalog.
Starters
A starter is a template that includes predefined services and application code that is
configured with a particular buildpack. There are two types of starters: Boilerplates and run
times. A starter might be application code that is written in a specific programming language,
or a combination of application code and a set of services.
Boilerplates
A boilerplate is a container for an application, its associated runtime environment, and
predefined services for a particular domain. You can use a boilerplate to quickly get up and
running. For example, you can select the Mobile Cloud boilerplate to host mobile and web
applications, and accelerate development time of server-side scripts by using the mobile app
template and software development kit (SDK).
Run times
A run time is the set of resources that is used to run an application. Bluemix provides runtime
environments as containers for different types of applications. The runtime environments are
integrated as buildpacks into Bluemix, and are automatically configured for use. Bluemix
supports polyglot programming and enables you to use different programming languages,
frameworks, services, and databases for developing applications.
You can use Bluemix to quickly develop applications in the most popular programming
languages, such as Java, JavaScript, Go, and PHP. Figure 4-7 shows some of the current
Bluemix run times.
65
Bluemix resiliency
Bluemix is designed to host scalable, resilient applications and application artifacts that can
both scale to meet your needs, and be highly available. Bluemix separates those components
that track the state of interactions (stateful) from those that do not (stateless). This separation
enables Bluemix to move applications flexibly as needed to achieve scalability and resiliency.
You can have one or more instances running for your application. When you have multiple
instances for one application, the application is uploaded only once. However, Bluemix
deploys the number of instances of the application requested, and distributes them across as
many VMs as possible.
66
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
You must save all persistent data in a stateful data store that is outside of your application,
such as on one of the data store services that are provided by Bluemix. Because anything
cached in memory or on disk might not be available even after a restart, you can use the
memory space or file system of a single Bluemix instance as a brief, single-transaction cache.
With a single-instance setup, the request to your application might be interrupted because of
the stateless nature of Bluemix.
A leading practice is to use at least three instances for each application to ensure the
availability of your application, where one or more of those instances is also in a different
Bluemix region. All Bluemix infrastructure, Cloud Foundry components, and IBM-specific
management components are highly available. Multiple instances of the infrastructure are
used to balance the load.
Bluemix security
All the same security concerns that apply to applications also apply to microservices. These
security risks can also be addressed in similar ways with microservice levels. Bluemix is
designed and built with secure engineering practices at the physical layer, software layer, and
communication layer. The Bluemix documentation contains more information about this topic:
https://www.ng.bluemix.net/docs/overview/sec_exec_ov.html
67
Runtime fidelity between the Liberty Profile and WebSphere Application Server Full Profile,
combined with Eclipse-based migration tools, make it easier to port existing monoliths to
WebSphere Liberty before decomposing them into microservices to run in Bluemix.
The Liberty run time and the WebSphere Developer Tools, which work with the Bluemix
Eclipse tools, make it easy to develop services locally and then deploy them to Bluemix. The
Liberty run time is available to download at no initial charge from the following website:
https://developer.ibm.com/wasdev/
Finally, Libertys zero-migration policy means that you should never be forced to make code
changes when Bluemix moves to newer versions of the run time.
68
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The Bluemix DevOps provides a set of services that enables you to adopt DevOps for this
ALM cycle, and more specifically an app delivery pipeline as a set of services. With IBM
Bluemix DevOps Services, you can develop, track, plan, and deploy software in one place.
From your projects, you can access everything that you need to build all types of apps. You
can use the services without any concern about how the services are hosted and delivered.
The following list includes some typical Bluemix DevOps Services spanning the ALM cycle:
Agile planning, through the Track & Plan service
A web IDE for editing and managing source control on a web browser or Eclipse Plug-in
for Bluemix (or integrate with existing Eclipse and work locally)
Source control management (SCM), through Git, IBM Rational Jazz SCM, or GitHub
Automated builds and deployments, through the Delivery Pipeline service
Integrated and Load Testing cycles through Testing services
Visibility, control, and analytics through Monitoring and Analytics services
Automatically increase or decrease the compute capacity through Auto-Scaling services
69
We suggest creating a separate Bluemix application and Bluemix DevOps Services project for
each microservice. See the following options for information about how to get started. There
are different flows for getting started, depending on if you are starting with an existing
application and you already have code, or are creating a new application. Start by creating
your environments on Bluemix.
Tech Lead
Manager
Mgr
Dev
Aud
Mgr
Dev
Aud
Mgr
Dev
Aud
70
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
If you are starting a new microservice application and do not yet have code, the easiest way
to get started is to create your application run time using one of the following approaches.
After that, decide how you want to manage and deploy your application code. The paragraphs
that follow describe the ways that you can create application run times without coding.
Figure 4-9 shows how to create an application run time from the Bluemix catalog.
Figure 4-9 Create an application run time from the Bluemix catalog
71
5. Click the Overview menu on the upper left to return to your application overview page.
See Figure 4-10.
Create an application run time from the Bluemix dashboard for Cloud Foundry
applications
Perform the following steps to create an application run time from the Bluemix dashboard for
Cloud Foundry applications:
1. From the Bluemix dashboard. Click the CREATE AN APP tile.
2. Select the web option and choose the run time that you want to run your microservices on.
Choose Community buildpacks if you dont see the programming language run time that
you want. New run times are being added.
3. Click the Start Coding submenu of your application to learn more about how to manage
code and do deployments to Bluemix.
4. Decide on how you want to manage code and do deployments. See the sections that
follow for an explanation of the available options.
5. Click the Overview menu on the upper left menu to return to your application overview
page.
72
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
[![Deploy to
Bluemix](https://bluemix.net/deploy/button.png)](https://github.com/fe01134/2048.g
it)
73
74
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
IBM DevOps Services supports deployment of Cloud Foundry Apps and containers:
Stages
Manages the flow of work through the pipeline. Stages have inputs,
job, and properties.
Jobs
Is where work is done. One or more within a stage. Build, deploy, and
test are the categories of jobs. An example job could be a script to
start integration testing services described in 4.2, Developing
microservices using Bluemix DevOps on page 68.
Triggers
Inputs
Defined on a stage, and they identify the artifacts used by the jobs
within a stage. They can be an SCM branch or the artifacts produced
by another job from a previous stage.
Properties
Defined on a stage, and values are passed to Jobs within the stage A
job can override a value and have it passed to a downstream job.
Figure 4-12 shows how Bluemix DevOps Services pipeline is configured to deploy to multiple
Bluemix regions. Bluemix DevOps Services on public instances can deploy to your dedicated
or local instances of Bluemix if there is accessible network connectivity. Pipeline also
supports deployment of containers.
Figure 4-12 Example multi-region IBM Bluemix DevOps Services delivery pipeline
75
Local client
GitHub
The Cloud Foundry command-line interface (CLI) enables you to administer your Bluemix
applications from your desktop client. There are various functions it provides for creating
spaces, applications, services, and users. It also provides functions for deploying and binding
services. In addition, you can manage the application run times and their bound services by
increasing the number of instances, allocating memory resources and other actions like
completing deployments.
You can also start bash scripts to populate or migrate databases. You must separately
download and install the Cloud Foundry CLI and Git. You can find instructions by clicking the
Start Coding menu from your application overview page in Bluemix.
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Bluemix automatically detects what type of application code you have when you deploy your
applications. You can also consider using a manifest file in situations where you prefer not to
specify additional cf push options on the command line when deploying an application.
The manifest file describes how to deploy the application to Bluemix, create services, and
bind those services to your application. See instructions about creating manifest files. You can
also specify memory and the number of instances used to run your application run time. For
more information about the manifest files, see the following website:
http://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html
For more detailed instructions about how to deploy your application to Bluemix using Cloud
Foundry CLI, follow the instructions on the following website:
https://www.ng.bluemix.net/docs/#starters/upload_app.html
After adding the required manifest file to your application, use the Cloud Foundry CLI cf push
command to deploy your application from your local client directly to Bluemix. Open a
separate Cloud Foundry CLI window to view the logs, and to troubleshoot failed deployments
when your application fails to start. Use the Cloud Foundry CLI help command to learn other
useful commands. You must initiate a cf push command each time you want to deploy new
tested code to Bluemix.
Tip: The most common deployment errors are caused by an invalid manifest.yml file
format. Read the documentation or reuse existing valid manifest files from other projects to
reduce the chance of errors in your manifest file. Additionally, you can create
http://cfmanigen.mybluemix.net/ or validate your manifest file using online manifest.yml
validators.
77
Make sure that you have created your Bluemix DevOps SCM project as a GitHub integrated
project. See the explanation in the next section.
78
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
79
Vertical scaling
Vertical scaling in Bluemix is the act of adding or removing resources for each instance of
your application. For example, the memory limit or the disk limit per application instance can
be adjusted. Figure 4-13 shows the scaling options in the Bluemix console.
Horizontal scaling
You can have one or more instances running for your application. When you request multiple
instances for one application, the application is only uploaded once. Bluemix deploys the
number of instances of the application requested, and distributes them across as many VMs
as possible. Each instance runs in its own isolated environment, and does not share memory
space or file system. They are identical nodes, and a load balancer is built into Bluemix to
route incoming traffic across all instances, as shown in Figure 4-14.
With a single instance setup, the request to your application might be interrupted because of
the stateless nature of Bluemix. A leading practice is to use at least three instances for each
application to ensure the availability of your application.
When using horizontal scaling, it is crucial to confirm that your application is designed
properly, and does not violate any cloud application rules. Review the following website for
leading practices:
http://www.12factor.net
80
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Auto-Scaling
The IBM Auto-Scaling for Bluemix is a DevOps service that enables you to automatically
increase or decrease the application instances. The number of instances are adjusted
dynamically based on the auto-scaling policy that you define. The policy enables you to use
metrics, such as CPU, memory, and Java virtual machine (JVM) heap, to define your scaling
policy. You can define multiple scaling rules for more than one metric type, as shown in
Figure 4-15.
There are many things to consider before deciding to scale your application. The performance
benefits of both horizontal and vertical scaling depend heavily on how your application is
written, and there is no one policy that can be applied to all. See the following article for a
more thorough explanation about, and implications of, scaling on Bluemix:
http://www.ibm.com/developerworks/cloud/library/cl-bluemix-autoscale
4.4.1 Communication
As mentioned earlier, in a microservice architecture, you end up having several independent
applications, with each running in their own isolated environments and written in the
languages and frameworks best for their individual purpose.
Each of these individual applications is deployed to Bluemix, and is accessed through their
own URL. For example, one of these microservices applications might have the following
URL:
myapplication-OrdersService.mybluemix.net
81
In Figure 4-16, you can see the microservices communicating with each other. Naturally,
microservice architecture supports both synchronous and asynchronous communication
between the different applications. Consider how we can implement each of these in Bluemix.
Synchronous
Imagine a scenario where our UI microservice application is querying a catalog microservice
application for a list of items to render. The catalog application needs to expose a URL
endpoint where the client (UI) can call to get the results. For this type of scenario, the
suggested protocol is to use REST over HTTP.
REST is a simple stateless architecture that uses existing web technology and protocols,
essentially HTTP. It is a simpler alternative to SOAP. The RESTful API establishes a mapping
between create, read, update, and delete operations and the corresponding POST, GET, PUT,
and DELETE HTTP actions.
Being an API, the RESTful interface is meant to be used by developers within application
programs, and not to be directly started by users. So in our scenario, the catalog application
exposes a RESTful API, and the UI application makes a call using the appropriate HTTP
action.
Because every application on Bluemix is on a different host name, if you are attempting to
make requests from one application to another using a client-side JavaScript, it is important to
know that you will run into Same-Origin Policy (SOP) that a browser imposes for security
issues. (Under the SOP, a web browser permits scripts contained in a first web page to
access data in a second web page, but only if both web pages have the same origin.)
Therefore, in our situation, this SOP does not permit JavaScript running and associated with
one Bluemix application to make requests to another web page related to another Bluemix
application. One solution is to make these requests on the server side. Alternatively, you can
implement a cross-origin resource sharing (CORS) solution, which allows a providing service
to define a whitelist of allowable hosts that are allowed to make requests, as outlined in the
following link:
https://developer.ibm.com/bluemix/2014/07/17/cross-origin-resource-sharing-bluemix
-apis/
82
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Asynchronous
Next, consider a scenario where one microservice application needs to start one or many
microservice applications, but we dont need to wait for the action to complete. In our store
scenario, when a user purchases an item using our UI application, it needs to tell the orders
application about the order, but it does not need to wait until the order is processed. The
orders app needs to alert an email notification or shipping microservice in a similar way.
Messaging is an effective way to communicate between these applications. Messaging uses
an asynchronous model, which means that an application that generates messages does not
have to run at the same time as an application that uses those messages. Reducing the
requirements for simultaneous availability reduces complexity, and can improve overall
availability. Messages can be sent to specific applications or distributed to many different
applications at the same time.
We can perform asynchronous work in various ways. It can queue large volumes of work, and
that work is then submitted once a day by a batch process. Alternatively, work can be
submitted immediately, and then processed as soon as the receiving application finishes
dealing with a previous request.
IBM MQ Light for Bluemix is a cloud-based messaging service that provides flexible and easy
to use messaging for Bluemix applications. IBM MQ Light provides an administratively light
solution to messaging. You can choose which API to use based on your requirements, your
system architecture, or your familiarity with a particular technology. You can use IBM MQ
Light to enable applications that use different run times to communicate with each other using
the AMQP protocol.
AMQP: AMQP stands for Advanced Message Queuing Protocol. It is an open standard
app layer protocol for message-oriented middleware, providing message orientation,
queuing, routing (both point-to-point and publish-and-subscribe), reliability, and security.
In our store order scenario, every time we receive a new order in the UI application, we can
implement a worker offload pattern where we have one or more Orders applications or
workers to share the work among themselves. As orders increase, we can simply add more
workers without having to change anything.
83
Session Cache
Session Cache is a caching service that stores and persists Java HTTP session objects to a
remote data grid. The data grid is a general-use grid that stores strings and objects. Session
Cache remotely leverages the caching capabilities of the data grid and enables you to store
session data. The session caching service provides linear scalability, predictable
performance, and fault tolerance of a web applications session data.
Session Cache provides a NoSQL-style, distributed key-value storage service, and provides
the following features:
Currently, this service is only supported for Java EE applications on Bluemix running on
Liberty for Java. To use this service, simply create and bind the service to your Liberty
application on Bluemix, and the necessary configuration is already created for you. No further
action is required to achieve session persistence. The Liberty buildpack installs the required
data cache code into the Liberty server, and generates cloud variables for the bound Session
Cache instance.
After you connect your application to the IBM Session Cache for Bluemix, you can monitor
your web applications caching usage. Click a service instance from the Bluemix console
dashboard in order to open the charts for your application.
Data Cache
For other types of applications, the IBM Data Cache service can be used to achieve similar
session persistence. It is a caching service that supports distributed caching scenarios for
web and mobile applications. It uses a data grid in which you can store key-value objects.
The service provides a language-neutral REST interface to access services. Use the HTTP
POST, GET, and DELETE operations to insert or update, get, and remove data from the cache.
Each REST operation begins and ends as an independent transaction to Data Cache. These
operations can be used to store and retrieve user session values.
84
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Bluemix also provides many third-party services, such as Redis, which can be used for
storing session data. However, it is currently a community service that is as-is, and is
provided for development and experimentation purposes only.
85
Some basic uses of the cf logs command are shown in Table 4-4.
Table 4-4 Basic uses of the cf logs command
cf logs appName -recent
cf logs appName
This command appends the logs from the application deployed to Bluemix
with the name appName.
When your application is deployed and somewhat stable, you want to use a logging service.
There are a couple of reasons to use a logging service. The first reason is that using cf logs
appName -recent only enables you to see so far back in your logs. Second is that logs are
deleted after the application restarts, and restarts can happen as a normal course of
operation, especially if you are practicing continuous integration and delivery. There are
several third-party logging services that you can use for Bluemix, including Logentries,
Papertrail, Splunk Storm, and SumoLogic.
86
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
87
You can learn more about IBM API Management Service in the documentation on the
following website:
https://www.ng.bluemix.net/docs/#services/APIManagement/index.html#gettingstartedapim
Another approach that requires more investment is to use Bluemix Local. Services deployed
in Bluemix Local are not visible outside your own corporate firewall. So although this option
does prevent visibility from the public, it does not prevent access to those people or
applications within your organization. You can enable access to your Bluemix Local
microservices from publicly hosted Bluemix applications by using the IBM Secure Gateway:
https://www.ng.bluemix.net/docs/#services/SecureGateway/index.html#gettingstarteds
ecuregateway
You can also use the IBM Cloud Integration Service:
https://www.ng.bluemix.net/docs/#services/CloudIntegration/index.html#gettingstart
edwithcloudintegation
To prevent access, you can also consider using API keys or tokens to only allow those with
API keys to access the microservice.
Service monitoring
Bluemix provides a Bluemix service status page (https://status.ng.bluemix.net/) to see
the current state of services and information regarding event outages. You can subscribe
to the Really Simple Syndication (RSS) feed. You could occasionally call this RSS feed to
detect error conditions and make corresponding mitigation actions in your application. A
useful capability would also be to be notified using email or text message when services
become unavailable.
Another approach to further improve resiliency in your application architecture is to consider
including Hystrix as part of your application architecture pattern. Yet another approach is to
monitor log files using service for error conditions, and send an email notification using
SendGrid or text message using Twillio. Finally, also consider using service monitoring and
notification services like Pingdom.
88
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Use a blue-green deployment approach where you have two production environments. The
live one is on blue servers, and the new microservice that will replace the existing service is
on the green server. The environments should be as identical as possible. After the green
server has tested, it becomes the live server by switching traffic to the green server.
Load balancing
Another approach to avoiding application failures is to providing load balancing across the
data center regions. If a data center goes down, being able to route requests to the same
applications deployed in another available data center can ensure continuity of microservices.
At the time of publication, IBM Bluemix does not provide a way to do application failover
across regions or public and local instances of Bluemix, but third-party services can provide
these services for use with Bluemix. For example, global load balancing can be handled using
domain name server (DNS) providers, such as Dyn or NSONE, which support geographic
routing and failover policies. You make one of these offerings as your authoritative name
server, and configure the policy that you want.
4.5.4 Versioning
After microservice versions are released into production, client feedback results in new
versions of the microservice being made available. Microservice developers are responsible
for providing clear direction on microservice versions as they go from beta to production and
providing notifications when they are sunset. Services listed in the Bluemix catalog typically
show if a service is experimental, beta, or generally available as part of their metadata.
Service versioning, however, is the responsibility of the service providers. The service version
of the APIs should be described in the documentation of the service. Bluemix does not
surface microservice versions in the user interface.
One approach for clearly communicating microservice versioning in Bluemix is to add version
identifiers to the microservice. Clients can then reach your microservice APIs endpoints
using one of the following methods:
URL path
Header
Accept_version_header
Parameters
https://www.googleapis.com/youtube/v3/playlists?key={YOUR_API_KEY}
The easiest approach is simply using a URL parameter, as shown in Example 4-3. In cases
where a version is not provided, you use the current version.
Example 4-3 Versioning microservice using URL parameter
https://www.googleapis.com/youtube/playlists?version=3beta&key={YOUR_API_KEY}
Tip: It is generally a good practice to avoid using version identifiers in the names of a
service, and to ensure that new changes do not break compatibility with an earlier version.
89
90
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 5.
91
Projects and source control, such as Git, GitHub, and Jazz SCM
Source code editing using the provided web integrated development environment (IDE)
Tracking and planning
A delivery pipeline that builds and deploys the code to IBM Bluemix
92 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Figure 5-1 shows an IBM DevOps Services starting point, as describe previously.
UI composition
Usage metering
Activities
Asynchronous messaging
93
Figure 5-2 The North Star Architecture for the DevOps Services system
The plan was to have this architecture in mind as the end goal, and use it to inform all tactical
steps toward its full realization. In order to ensure this goal, we devised a set of rules for code
transformation:
1. When adding an entirely new feature, write it by following the North Star architecture to the
fullest.
2. When attempting a refactoring of an existing feature, assess the extent of the rewrite. If
the cost of rewrite is comparable to writing a new feature, take the opportunity to
implement it as a microservice using the new architecture, and retire the old feature in the
monolith.
3. Repeat step 2 until the monolith dissolves.
Our first microservice followed Rule 2. We wanted to redesign the way we served tutorials to
make it easier for content authors to be productive, and to update the content without the slow
and costly monolith redeployment. We stood up a Node.js microservice serving tutorial
content authored in Markdown, and pointed at it using the Apache reverse proxy.
This is an example of the incremental evolution that all existing systems must undergo. Our
users did not notice any disruption, except that new tutorials arrived at a faster cadence, and
we were able to react to typographical errors and technical errors with much more agility.
94 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
95
96 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
One of the lessons of any large web property is that more often than not we deal with a site
and an app (or multiple apps) folded into one. Such an arrangement is ideal for microservice
architecture, so that different parts can be evolved at their own speed, and use the best
technology for their intended use. See the following website for more information:
http://dejanglozic.com/2015/01/26/should-i-build-a-site-or-an-app-yes/comment-page-1/
Figure 5-3 High-level architecture of the Bluemix console before the microservice evolution
All of the individual features of Bluemix were part of the single-page app, served by a single
Java EE server, and calling the Cloud Foundry API for most of the state. When a change was
made to the home page or one of the solution pages (all publicly accessible, crawlable
content), the entire application had to be redeployed. After a while, this becomes a significant
detriment to further evolution of the platform.
Of course, Bluemix is a production system that many applications rely on for continuous
availability, and it had to be evolved with continuity of operation. We have therefore picked a
portion that is relatively straightforward to peel off: Public content.
97
You might notice that this parallels our experience with IBM DevOps Services. The first
feature to peel off there were Tutorials. High-churn, frequently updated content is typically first
to create a bottleneck, because more sensitive, dynamic parts of the system are normally
updated less often and with greater care.
98 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
99
To further minimize UI composition resource usage, callers are encouraged to cache the
result for a short period of time (5 - 10 minutes) to improve performance and reduce pressure
on the common microservice.
The advantage of this approach is that it is stack-neutral. It is reduced to basic HTTP and
HTML, which ensures that any microservice, irrespective of the chosen technology, can use it
while serving pages. In addition, it uses the normal OAuth2 bearer token authentication to
pass the user profile information. This ensures that common areas that are customized to the
user can be served by a single common service.
Of course, the service can also serve a public (unauthenticated) version of the common
element. Figure 5-5 shows the UI composition of the Bluemix landing page. The common
microservice provides header and footer snippets, which are combined with the content and
served as a complete page by the Landing microservice. This process is repeated for all of
the pages using these common elements. Styles and JavaScript are sourced using normal
HTML mechanisms.
100 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
In our case, we had to solve authentication sharing, UI composition, and reverse proxy issues
before proceeding. After these problems were solved, we were able to address areas with the
most churn, such as Home and Solutions. With the architecture and DevOps mechanisms in
place, the continuation of the evolution is simply a matter of identifying the next area of the
system to address, and switching the proxy to the newly erected microservices. At the time of
writing of this book, this process is still ongoing, but we can easily predict where it will end
(after all, we are now used to the North Star architecture approach that we continue to follow).
Figure 5-6 shows the wanted end-goal of the Bluemix console microservice transformation.
All features of the site are served by dedicated microservices and can follow their own
development and deployment schedule. In addition, they can be optimized for the particular
task (serving content, or assisting users with apps, services, containers, and VMs in a highly
dynamic and interactive fashion). There is no need for a one size fits all technology approach
any more.
Figure 5-6 The wanted end-goal of the Bluemix console microservice transformation
101
102 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Figure 5-7 A detail of the Bluemix console showing microservices powering the console (dev space): A great example of
self-hosting
103
Bluemix PaaS
Ser vices
IaaS ++ platform
Devops Image
Baker y
Devops Console
Dynamic Routing
Externa l Monitoring
and Aler ting
Microservice
Monitoring
Chaos, Complianc e,
Se curity Testing
Softlayer IaaS
Image Management
Availability Zones
Image management
Compute and Storage provisioning
Auto recovery, auto scaling
Availability zones
104 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Services layer
On top of the CSF layer, the Watson innovation team continues leveraging the open source
software for services-level orchestration:
Client-side load balancing, such as Ribbon and HAProxy
Services registration, such as Eureka, Etcd
Uptime for service heath checks
Microservices architecture and relevant cloud design patterns have been applying
extensively, such as circuit breaker, event sourcing, and so on.
12. Monitoring
(Uptime)
5. Pod-1
(DataPower, Zuul)
SERVICE
LOGIC
3. Imaginator
Service
Your
built code
2. Tested
images /w
required
agents
1. Supported
application
libraries
10. Logging
(Logstash.
Kibana)
11. Metrics
(Graphite
Grafana
Seyren)
7. Dynamic
Config
8. Service
Discovery
(Archaius)
(Eureka)
9. Load
Balancers
Chaos Monkeys)
IBM Confidential
105
Important: IaaS++ is a cloud operating environment built by IBM and used as an initial
internal offering. There are plans to make this available in external offerings as appropriate.
Next, we describe in detail each component that makes up IaaS++ in the following sections.
107
Figure 5-10 shows the Watson services that are currently available in a Bluemix platform.
There are currently 13 Watson services available in Bluemix, most of which are brought and
orchestrated to the cloud environment through a process thats centered around a
microservice architecture approach.
108 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Decomposition to microservices
Overall, the system has been partitioned to several building stacks, and then split up to
smaller services using the single responsibility principle (where each service has a small set
of responsibilities). The following list provides some examples:
Logging stack contains loosely coupled services, such as ELK, which internally interact
with each other to perform logging activities of the whole system. This is a centralized
logging framework, so that we no longer need to ssh onto individual nodes and inspect
each log. With Kibana, users can query and filter against all nodes and see log results
from a single Kibana dashboard.
Monitoring stack contains a bunch of microservices, which choreographically interact with
each other to visually gain insights about the health status of all Watson services in a
real-time manner that consequently reduces the time needed to discover and recover from
a bad operational event. Grafana is used as a centralized monitoring dashboard to view
metrics for all nodes in the system.
Eureka service is being used as a service registry where all other services self-identify
and register themselves as a specific service, and a service discovery responding to
queries about location of a specific service instance.
In order for services to onboard onto IaaS++, they need to integrate with the Common
Service Broker microservice for provision, bind, and catalog requests from Bluemix.
Authentication service is responsible for authenticating requests coming from a Bluemix
application into Watson developer platform.
109
For service recovery, each service instance runs an agent (Karyon to self register to the
Eureka service directory, and Eureka client with a caching mechanism to locate a service
instance and keep track of its healthy status). Asgard is responsible for calling APIs on the
SoftLayer autoscale, to create clusters with the wanted number of instances. If any instance
stopped working (stopped heart beating), the auto-scaler created a new instance and place
into the cluster.
The client-side load balancer gets information about a target service from the service registry,
and routes and load balances the request to the appropriate service instance in the target
service cluster. Figure 5-11 shows an example in detail of the interaction mechanism between
services through service registry and discovery.
Target service cluster
Service instance
Instance 1
Client
loadbalancer
Instance 2
Instance 3
Service
registry
client
Service
discovery
client
Discover
services
Register
service
Service registry
Register
services
Deployment
To protect anybody from going directly into a server to modify anything, the immutable
approach has been used, which means that the deployment needs to start from an image.
The service development team is provided with an Ubuntu base image with the necessary
setting to harden the security and other runtime environments.
The development team has to bring in a Debian package, which contains the code and all
dependencies that the code that runs on top of the base image might have. The image baker
then combines those parts, provisions a deployable image, and provides a SoftLayer CCI
image for deployment through the DevOps console.
From a deployment perspective, IaaS++ leverages the Canary red/black deployment
mechanism. Deployable code is placed in a new ASG alongside the existing one, and the
traffic to the services starts being ported to the new ASG after the code is pushed out. This
approach helps to build an automated confidence level about the readiness of the new code,
and provides the ability to quickly switch back to the old version if needed, which ensures that
there are no destructive or in-place upgrades.
110 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Figure 5-12 shows the process of how to onboard a Watson service to a cloud environment,
along with the major IaaS++ components interaction.
"$
'
*
"&+$
"!&"$!
$!
%"$
"
' *
#.$!1''
##
$(
%
"!$(
$"$
$( !%&!
&#")$
$#&
$(
# !&&"!
''
$%&$
Service
'$
registry
$(
)/!
)!*+)2
$+"!
#!%+
)/!
'$
!*&/)2
!&
#!%+
+%&$*
%"$
#&
%"$
+%&$*.'$!
#&
+$!
$&
"!&"$
$'&+
$("
"&
"%&%
%##$
&
%"($
!
%"$
#"+
(#%
#'%
#
%$
%&%$
#'
"%&%
$(
# !&&"!
/!0
'!&'23-13
%
$(
# !&&"!
/#"+ 0
!&"$
/
," &,$0
111
112 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Part 2
Part
Example scenarios
using the microservices
approach
In this part, we describe three example scenarios that were developed using the
microservices approach. The following scenarios are described:
Chapter 6, Scenario 1: Transforming a monolithic application to use microservices
(CloudTrader) on page 115
Chapter 7, Scenario 2: Microservices built on Bluemix on page 123
Chapter 8, Scenario 3: Modifying the Acme Air application and adding fault tolerance
capabilities on page 131
113
114 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 6.
Scenario 1: Transforming a
monolithic application to use
microservices (CloudTrader)
In this chapter, we demonstrate how to bring code from IBM DevOps Services into your
Eclipse workspace, build and deploy the application to IBM Bluemix, and use database and
other services in the cloud. We also externalize a portion of the business logic from a
monolithic application into a new microservice developed entirely in Bluemix. To demonstrate
this process, we work with the CloudTrader sample application.
This scenario exemplifies a typical modernization of an existing application by selecting a
relatively small component or piece of functionality, isolating it, and provisioning a new
component in a language and platform more conducive to constant changes. To increase the
agility of delivering new features, we set up a Bluemix Delivery Pipeline for the new
microservice.
This chapter has the following sections:
115
116 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The steps involved in deploying the original CloudTrader to Bluemix, including the source
code, can be found on the following website:
http://www.ibm.com/developerworks/cloud/library/cl-cloudtrader-app/index.html
Orders
Quotes
Accounts
Holdings
In this scenario, we externalize the related business logic of two components from the
previous list to demonstrate how a monolithic application can be modernized and refactored
in small increments. The quotes and accounts related logic is coded into a Quote
microservice and an Account microservice.
The same approach we use for these two business functions can be used for the other
entities listed.
117
118 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Figure 6-4 shows the CloudTrader components overview with an externalized Quote
microservice.
119
To automate the builds and deployments to IBM Bluemix, we use the IBM Continuous
Delivery Pipeline for Bluemix (the Delivery Pipeline service). This is shown in Figure 6-6 on
page 121. As you develop an app in the cloud, you can choose from several build types. You
can provide the build script, and IBM Bluemix DevOps Services runs it; you dont need to set
up build systems. Then, with one click, you can automatically deploy your app to one or many
Bluemix spaces, public Cloud Foundry servers, or Docker containers on IBM Containers.
Build jobs compile and package your app source code from Git or Jazz source control
management (SCM) repositories. The build jobs produce deployable artifacts, such as web
archive (WAR) files or Docker containers for IBM Containers. In addition, you can run unit
tests within your build automatically. Each time the source code changes, a build is triggered.
A deployment job takes output from a build job and deploys it to either IBM Containers or
Cloud Foundry servers, such as Bluemix.
120 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Figure 6-6 Bluemix DevOps pipeline stages for the CloudTraderQuoteMSA microservice
In our sample, we built a simple Bluemix DevOps pipeline with three stages, to build, deploy,
and run an automated battery of unit tests. The pipeline can be as complex as necessary, to
suit the needs of the testing organization.
121
122 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 7.
123
124 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Next, we more closely examine how we implement each of these microservices. These
microservices are implemented as independent stand-alone applications in Bluemix. So, we
are developing four different applications. Each of the four applications provides different
business capabilities, and has been written in a different language. The variability in
programming languages demonstrates the options available in Bluemix. The decision about
which language to use can be based on several factors to simplify the development tasks,
such as the availability of skills or the suitability of the language.
Bluemix offers other types of middleware services, such as database, caching, and
monitoring. Our applications can consume one or many of these services. Next, we look at
each of the microservice applications in more detail. This variability in language choice does
not prevent the microservices from running in a single platform and using common features,
such as single sign-on (SSO) or central logging.
Language
We need a language that will help us build a high-throughput, easily scalable application that
can handle thousands of simultaneous connections. We wont be performing CPU-intensive
operations, but simply a layer to help us interact with a database. Node.js uses a
non-blocking, event-driven input/output (I/O) model, and provides an extremely lightweight
container that is suitable for what we are doing. The WebSphere Application Server Liberty
buildpack on Bluemix offers us an enterprise-grade Java Platform, Enterprise Edition
(Java EE) application server, while still being extremely lightweight and dynamic.
Chapter 7. Scenario 2: Microservices built on Bluemix
125
Interface
The application needs a way to receive requests for items, and also to provide the ability to
modify the items to the catalog. Creating a Representational State Transfer (REST)
application programming interface (API) sounds like an optimal choice for this type of
interface, because it provides a widely accepted standard for interacting with resources.
Node.js with the Express framework provides a way to create a minimalist web framework for
us to create this interface. Express is a module for Node.js that enables you to create a REST
API by enabling us to bind functions to incoming requests using Hypertext Transfer Protocol
(HTTP) methods. We use the following HTTP methods:
GET. Get all items, or one particular item.
POST. Create a new item.
DELETE. Remove an item.
Database
Obviously, the application needs to be persisting these items into a database. Each item in
the store can be represented as a JavaScript Object Notation (JSON) data type. An
asynchronous JSON handling NoSQL database matches perfectly with our app, because it
provides a flexible, schema-less data model to handle our items. One of the many databases
that Bluemix has to offer is Cloudant, a distributed, scalable NoSQL database as a service.
Get it running
Now that we selected the language, framework, and database, we are ready to start writing
some code and deploy our application. The sample code is available as a Git project on IBM
DevOps Services. The following link outlines detailed steps to deploy this online store
application, and provides access to all of the source code:
https://developer.ibm.com/bluemix/2015/03/16/sample-application-using-microservice
s-bluemix/
Before we get into the deployment steps, examine the manifest.yml file at the root of the
project. A manifest.yml file defines the application to Bluemix. It can contain various
information about the application, such as the name, URL, amount of memory, and number of
instances. It also contains the names of any Bluemix-provided services needed by our app.
For example, we decided that this catalog application requires the Cloudant service.
The documentation in the previous link contains a Deploy To Bluemix button that facilitates
the deployment from source code directly to a running application in Bluemix. The button
creates your own private DevOps Services project with a copy of the sample source. It also
uses manifest.yml to deploy the application to your Bluemix.
7.2.2 Orders
The next application we tackle is the order management application. When a user buys an
item from the UI (or any other future channel), the order service is expected to receive and
process the order.
Language
Due to the nature of this application handling customer orders and billing information, failures
are not acceptable for this service, and security is of utmost importance. We have selected to
use Java EE, because this app needs a technology stack that is robust, well-supported,
standards-driven, able to provide transactional support, and is industry-proven.
126 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Database
Again, to match our run time, we want to pick a proven, secure, relational database that can
handle the transactional workloads. Bluemix offers the SQLDB service, an on-demand
relational database service powered by IBM DB2.
Interface
The consumer of this service needs to be able to notify this orders application when a new
order is generated, and also provide information about past orders. Similar to the Catalog
application in the previous section, we create a RESTful interface using Java EE Java API for
RESTful Web Services (JAX-RS). The WebSphere Liberty buildpack on Bluemix supports
Enterprise JavaBeans (EJB) applications that are written to the EJB Lite subset of the EJB
3.1 specification, which is ready for immediate use without needing any further configuration.
Get it running
Again, use the following documentation to clone the sample source and deploy to Bluemix. To
understand how the application is being deployed, review the manifest.yml file:
https://developer.ibm.com/bluemix/2015/03/16/sample-application-using-microservice
s-bluemix/
7.2.3 Shipping
This is our worker application, which waits for new orders and then proceeds to do
shipping-related processing. This processing can take an undetermined amount of time to
complete. The Orders application needs to asynchronously inform this Shipping application
about a new order. However, it does not wait for the Shipping application to complete its work.
We implement the messaging worker offload pattern mentioned in 2.3, REST API and
messaging on page 33, where this worker uses a messaging service to know when
something interesting (a new order) happens, and then proceed to do the work.
Several instances of this worker application could exist, as in this example, which distributes
the work among each of the instances. If the load increases, additional worker applications
can be created by simply increasing the number of instances, and without the need to alter
the application.
Because this application receives its input from a messaging service, and not a web or REST
interface, there is not a Uniform Resource Locator (URL) route to access this background
worker application.
Messaging
The IBM MQ Light for Bluemix is a cloud-based messaging service that provides flexible and
easy-to-use messaging for Bluemix applications. IBM MQ Light provides an administratively
light solution to messaging. We use this feature to handle the message communication
between the Orders application and this Shipping application.
Language
To make this sample stretch some of the wide run time and language framework capabilities
of Bluemix, we decided to implement this worker application using Java EE message-driven
Enterprise JavaBeans, which integrates seamlessly with the messaging service. This
framework can be easily extended to solve larger business domain problems as needed, due
to the self-contained and scalable nature of EJB components.
127
Get it running
Again, use the following documentation to clone the sample source and deploy to Bluemix. To
understand how the application is being deployed, review the manifest.yml file:
https://developer.ibm.com/bluemix/2015/03/16/sample-application-using-microservice
s-bluemix/
7.2.4 UI
This is the face of our store. When developing a UI, many aspects, such as JavaScript
libraries, usability, globalization, translation, and security, need to be carefully considered.
However, for the sake of keeping things simple, this sample has a minimalist web page.
Language
It is no surprise that PHP Hypertext Preprocessor (PHP) is a common language for writing
web user interfaces. It gives the developers control over how they want to structure their
server-side and client-side code. However, the reason for picking PHP might also simply be
that your UI developer is only comfortable with PHP.
128 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
7.3.2 Monitoring
Bluemix provides the Monitoring and Analytics service, which provides insights about how
your application is performing. Availability and performance metrics are crucial when running
a business, and having the platform provide this data is extremely valuable. You can bind the
Monitoring and Analytics service to an application using the steps provided in the Bluemix
documentation. The service can provide dashboards, such as the ones shown in Figure 7-2
and Figure 7-3 on page 130.
129
If the online store application is running sluggishly, you can see if the root cause is from the
response time of the REST endpoints of the Catalog application. From here, you can
determine if you need to investigate a performance problem, or scale the application using
manual or an auto-scaling policy (horizontal scaling). The memory usage chart can be used
to evaluate if more memory needs to be allocated per instance (vertical scaling).
7.3.3 Scaling
One of the great benefits of running your applications on the cloud (when your application is
written properly) is the ease of scaling. In our sample scenario, as our store grows in
popularity, the UI application makes many requests to our Catalog service. If you add another
mobile front-end, that further increases the calls to our service. Bluemix enables you to easily
scale the application horizontally by simply increasing the number of instances.
You can increase your instances from one to five and, in about a minute, you should have all
five instances serving at the same endpoint behind a load balancer. Each of the instances
runs in its own lightweight container, and they do not share the same memory or file system.
However, all five instances are bound to the same database service. The scaling of the
database service is handled by the provider of the service and the service plan you select.
Bluemix also provides an Auto-Scaling service, which can automatically increase or decrease
the instances of your application by the use of the policy that you define. For example, you
can protect your application instance from failing due to running out of memory by creating
rules to scale up when memory or Java virtual machine (JVM) Heap reaches 80% of capacity.
130 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Chapter 8.
131
The trend for web API calls has changed in the past few years to include many more mobile
users and business-to-business web APIs in addition to the traditional browser-facing clients.
The redesign philosophy used for optimizing the Acme Air application was to embrace the
different devices that would be used to access the application.
132 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
To meet these changing business requirements, a mobile interface feature was added. This
feature enables the application to reach users on their remote devices and tie systems of
engagement to the back-end system. The IBM Worklight server technology (now known as
IBM MobileFirst platform) was used to provide a secure, scalable, native mobile-facing
environment.
Log in to Bluemix
You should have previously signed up for Bluemix at http://bluemix.net. You should have
also installed the Cloud Foundry command-line interface (CF CLI), which is available on the
following website:
https://github.com/cloudfoundry/cli#downloads
Log in to Bluemix using the CF CLI. The CF commands to do this are shown in Example 8-1.
Example 8-1 CF commands to login to Bluemix
cf api api.ng.bluemix.net
cf login
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
133
The screen capture in Figure 8-2 shows a cf login. You likely have only one organization
and one space, and dont need to select these from a list, as is the case in Figure 8-2.
134 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
In your Bluemix dashboard, you should see the Acme Air web app you just pushed, as shown
in Figure 8-4.
Note that the web app is not started yet. We need to create a data source for it first, before
starting it.
MongoDB
The following command creates a mongodb service with a name of acmeairMongo:
cf create-service mongodb 100 acmeairMongo
The screen capture in Figure 8-5 shows the execution of this create-service command.
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
135
In your Bluemix dashboard, you should see the MongoDB service that you just created, as
shown in Figure 8-6.
Cloudant
For Cloudant, the following CF command creates the database:
cf create-service cloudantNoSQLDB Shared acmeairCL
Figure 8-7 shows the execution of the create-service command for Cloudant.
136 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
In your Bluemix dashboard, you should see the Cloudant service that you just created, as
shown in Figure 8-8.
For Cloudant, we need to create the database and the search index. In the source code, you
have the following file:
/document/DDL/cloudant.ddl
Use this file to create the database and search index.
By this point, we have the Acme Air web app deployed and a database created. Next, we
need to bind the web app to the database service.
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
137
Do not forget to replace <uid> with the unique ID you used to name your app. The screen
capture in Figure 8-9 shows the execution of a bind.
You can also start the web app from the Bluemix dashboard. When the application is started,
go to the route in a web browser. The following route is an example:
http://acmeair-nodejs-<uid>.mybluemix.net
138 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
You should see the Acme Air home page shown in Figure 8-11.
The first thing you must do is click the Load Database action in the top menu bar. You can
now log in, search for flights, and so forth.
139
For the auth-service, the customersession methods from customerservice were moved to a
separate Representational State Transfer (REST) service. The web app was changed to use
REST calls rather than local calls. The authentication service is called on every request, so
the new design supports better scalability of subsystems. A central database is used by both
the web front end and the authservice.
Figure 8-12 shows the Acme Air application architecture for the microservices version.
To implement a microservices architecture for this application, the main Node.js application
delegates to the authorization service Node.js application hosted on host:port, defined in
AUTH_SERVICE. End-to-end requests from a client include REST endpoints, business logic, and
data tier interactions.
The Acme Air application enables users to choose a data store of either Cloudant, MongoDB
or Cassandra. Figure 8-18 on page 145 shows the application deployed in Bluemix. A
MongoDB (acmeairMongo) is used by both the web front end and the authentication
microservice (uniquely named acmeair-nodejs-sdaya and authservice-sdaya in our
deployment).
Log in to Bluemix
Log in to Bluemix as described earlier using the cf api and cf login commands.
140 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Configure the Acme Air web app to use the authentication service
For the Acme Air web app to use the authentication service rather than the authentication
mechanism built into it, we need to set an environment variable called AUTH_SERVICE and give
it the Uniform Resource Locator (URL) of the authentication service. The following CF
command creates this environment variable:
cf set-env acmeair-nodejs-<uid> AUTH_SERVICE authservice-<uid>.mybluemix.net:80
Figure 8-13 shows the result of this command.
In the Bluemix dashboard under Environment Variables for the Acme Air web app, you should
see the environment variable that you just created. It is in the USER-DEFINED tab, as shown
in Figure 8-14.
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
141
You need to restart the Acme Air web app for this environment variable to be picked up. You
might want to enable Hystrix first, before restarting the app.
Enable Hystrix
Enabling the use of Hystrix is also done using an environment variable. An environment
variable named enableHystrix needs to be set to true using the following CF command:
cf set-env acmeair-nodejs-<uid> enableHystrix true
Again, if you go to the Bluemix dashboard, you can see the enableHystrix environment
variable set to true, as shown in Figure 8-15.
Restart the Acme Air web app and try to perform a login. This now uses the authentication
service.
142 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Hystrix Dashboard enables us to be alerted, make decisions, affect change, and see results
in seconds. Adding Hystrix-like functionality (command pattern, circuit breaker, and metrics)
to your microservices architecture helps defend your application by providing a greater
tolerance of latency and failure. Overall, this helps you gradually degrade rather than fail
completely.
Applications in a complex distributed architecture have many dependencies, each of which is
susceptible to failure. If the host application is not isolated from these external failures, the
host application is at risk of failure whenever a dependency fails. Threads and semaphores
can be isolated with circuit breakers.
By implementing a command pattern + circuit breaker design, we can achieve fault-tolerance
and resilience through fail-fast. Real-time monitoring and configuration changes enable you to
see service and property changes take effect immediately.
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
143
To monitor the Acme Air authentication service, you need to monitor the following Hystrix
event stream:
http://acmeair-nodejs-<uid>.mybluemix.net/rest/api/hystrix.stream
Specify that stream on the Hystrix Dashboard home page and click the Monitor Stream
button. You can now see the details, as shown in Figure 8-17.
144 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
The screen capture in Figure 8-18 shows all of the Acme Air components for the
microservices mode in the Bluemix dashboard.
New design
A benefit seen with microservices architecture is the ability to continuously update systems in
real time, deploying code features in a short time and measuring instant responses. Creating
a highly agile and highly available service on the cloud is possible if you prepare and plan for
the occurrence of broken or failed components. Also consider how to keep the other services
functioning, not causing a total application failure. Hystrix offers a fault tolerance solution to
defend your application.
The application needed the ability to scale to billions of web API calls per day, and to support
mobile user interactions. The original Acme Air monolithic application was changed to
efficiently use the capabilities of cloud deployment, microservices architecture, and Netflix
OSS Hystrix monitoring.
The end result is a fault-tolerant, high-performing application design that puts control in the
hands of the development team. The microservices design provides better fault tolerance of
the main web application with regards to dependent services.
Chapter 8. Scenario 3: Modifying the Acme Air application and adding fault tolerance capabilities
145
146 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Related publications
The publications listed in this section are considered particularly suitable for a more detailed
description of the topics covered in this book.
IBM Redbooks
The following IBM Redbooks publications provide additional information about the topic in
this document. Note that some publications referenced in this list might be available in
softcopy only:
Smart SOA Connectivity Patterns: Unleash the Power of IBM WebSphere Connectivity
Portfolio, SG24-7944
You can search for, view, download or order these documents and other Redbooks,
Redpapers, Web Docs, draft and additional materials, at the following website:
ibm.com/redbooks
Other publications
This publication is also relevant as a further information source:
Building Microservices, 978-1491950357
Online resources
These websites are also relevant as further information sources:
IBM Bluemix home page:
https://bluemix.net
IBM Bluemix main documentation page:
https://www.ng.bluemix.net/docs/
IBM SOA solutions website:
http://www-01.ibm.com/software/solutions/soa/
IBM developerWorks article about autoscaling on Bluemix:
http://www.ibm.com/developerworks/cloud/library/cl-bluemix-autoscale/
Information about creating Bluemix spaces:
https://www.ng.bluemix.net/docs/#acctmgmt/index.html#acctmgmt
Information about Deploy To Bluemix button:
https://www.ng.bluemix.net/docs/#manageapps/index-gentopic2.html#appdeploy
Information about manifest files:
http://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html
147
Information about deploying your application using the Cloud Foundry CLI:
https://www.ng.bluemix.net/docs/#starters/upload_app.html
Information about IBM Cloud Integration service:
https://www.ng.bluemix.net/docs/#services/CloudIntegration/index.html#gettingst
artedwithcloudintegation
Information about IBM Secure Gateway:
https://www.ng.bluemix.net/docs/#services/SecureGateway/index.html#gettingstart
edsecuregateway
IBM SoftLayer website:
http://www.SoftLayer.com
148 Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
Microservices from Theory to Practice: Creating Applications in IBM Bluemix Using the Microservices Approach
(0.2spine)
0.17<->0.473
90<->249 pages
Back cover
SG24-8275-00
ISBN 0738440817
Printed in U.S.A.
ibm.com/redbooks