Originally presented at CF Summit Europe 2017 in Basel, Switzerland. The abstract of the talk was:
The Bluemix UI (which runs on CloudFoundry) is the front-end to Bluemix, IBM’s open cloud hosting platform. The original implementation as a single-page, monolithic Java web app brought with it many demons, such as poor performance, lack of scalability, inability to push small updates, and difficulty for other teams to contribute code. Over the last 2 years, the team has been on a mission to slay these demons by embracing cloud native principles and splitting the monolith into smaller Node.js microservices. The effort to migrate to a more modern and scalable architecture has paid large dividends, but has also left behind a few battle scars from wrestling with the added complexity cloud native can bring. The team had to tackle problems in a wide variety of areas, including: large-scale deployments, continuous integration, monitoring, problem determination, high availability, and security. Tony Erwin will discuss the advantages of microservice architectures, ways that Node.js has increased developer productivity, approaches to phasing microservices into a live product, and real-life lessons learned in the deployment and management of Node.js microservices across multiple CloudFoundry environments. His war stories will prepare you to wage your own battles against monoliths everywhere -- happy slaying!
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
To Kill a Monolith: Slaying the Demons of a Monolith with Node.js Microservices on Cloud Foundry
1. To Kill a Monolith: Slaying the Demons of a
Monolith with Node.js Microservices
on Cloud Foundry
Tony Erwin, Senior Software Engineer, IBM
aerwin@us.ibm.com
2. Agenda
• Origins of the Bluemix UI
• Demons of the Monolith
• Slaying Demons with a Microservices Architecture
• New Demons to Slay
3. Bluemix UI – Origins as a Monolith
• Serves as front-end to Bluemix (IBM’s open cloud offering)
• Lets users create, view, and manage CF resources, containers,
virtual servers, user accounts, billing/usage, etc.
• Runs on top of Bluemix PaaS Layer (Cloud Foundry)
• Started as single-page application (SPA) to provide desktop-like
experience in the browser
• All HTML, CSS, and JavaScript loaded within single web page
• Served from a single Java app
• State-of-the-art not all that long ago
• Dojo + J2EE was the most common stack in IBM when Bluemix UI dev
started (~4 years ago)
• SPA still popular (AngularJS, Ember.js etc.)
4. Bluemix UI – Many Components
Home Dashboard
Users
And
More!
Resource Details Billing
6. Demons of the Monolith
• Bad performance
• Heavy weight JavaScript loaded to browser is slow
• Volume of client-initiated AJAX requests creates bottlenecks
• Difficult to integrate code from other teams (especially when
they use different stacks)
• Have to push whole product even for small changes
• Poor SEO
• New hires want nothing to do with Dojo
8. Weapons of Microservices
• Aids migration to more modern, lighter-weight stack without starting over
• Improves performance with small services optimized for speed and page size
• Increases developer productivity with less chance of breaking other parts of
the product
• Loosely-coupled services can deploy at their own schedule
• Teams use stack of their choosing
• Teams don’t have to wait on others
• Leads to improved SEO
• Proxy facilitates “clean” URLs
• Server side generation results in crawlable content
• Improves cross-team UI consistency via microservice composition
9. Microservice Pattern
UI microservice:
• Written with Node.js
• Serves lightweight HTML, CSS,
JS (simplest approach that works)
• Uses server-side templating
(Dust.js) to make as much data
available to the client as possible
for fast rendering & SEO
• Invokes Common Header
microservice to get HTML for
shared header to include in initial
payload
• Consults shared session store for
user token, etc.
• Leverages backend APIs and/or
API microservices as appropriate
Node.js (w/
Dust.js)
Backend APIs (CF, Containers, VMs, BSS, MCCP, etc.)
Bluemix UI (Client)
Cloud Foundry
Proxy
Common
Header
• HTML
• CSS
• JavaScript (Vanilla, Polymer.js, React, Angular)
API Microservice
10. Page Composition w/ Microservices
header
inline
combined
Common
Microservice
11. Migration, Phase 1
• Delivered Feb 2015
• Introduced proxy layer to
route requests to different
services based on URL path
• Added three microservices
behind the proxy (alongside
Java code)
• Leveraged two additional
CF services:
• Data Cache for shared
session
• NoSQL DB for data storage
Solutions
Catalog Dashboard
Resource
Details
Account
Backend APIs (CF, Containers, VMs, BSS, MCCP, etc.)
DB/2
Bluemix UI Server
(Monolith)
Bluemix UI (Client)
Cloud Foundry
Proxy
Common
Header
Session
Store
NoSQL
DB
Home
…
12. Migration, Phase 2
• Delivered Feb 2016
• 90%+ of migration
complete
Home Catalog …
Resource
Details
Dashboard
Backend APIs (CF, Containers, VMs, BSS, MCCP, etc.)
Cloud
Foundry Proxy
Common
Monitoring
Framework
Account
Bluemix UI (Client)
Java Server
(Monolith)
Session
Store
NoSQL
DB
DB/2
13. Migration End Goal
• More or less current
state in production,
except for:
• Java app for certain APIs
still exists
• Small amount of legacy
Dojo code
Home Catalog … DashboardPricing
Orgs/
Spaces
Backend APIs (CF, Containers, VMs, BSS, MCCP, etc.)
Bluemix UI (Client)
Bluemix
PaaS Proxy
Common
Monitoring
Framework
Session
Store
NoSQL
DB
Cloud Foundry
14. Plugin Architecture
• Roughly 15 teams
outside of the
core UI team
plugin via the
proxy to look and
behave like one
large product
Home Catalog … DashboardPricing
Orgs/
Spaces
Backend APIs (CF, Containers, VMs, BSS, MCCP, etc.)
Bluemix UI (Client)
Bluemix
PaaS Proxy
Common
Monitoring
Framework
Cloud Foundry
Watson
Internet of
Things
OpenWhisk Containers
Mobile …
16. New Demons to Slay
• More moving parts, more complexity
• Build pipeline becomes all the more important
• Collecting federated status, monitoring health of the system
• Granularity of microservices vs. memory allocation
• Monolith: 3 instances of Java app = 6 GB
• New console: ~27 apps, ~95 instances, ~55.5 GB
• Seamless navigation with existing monolith
• Blue-green deployments
• Promoting uniformity & consistency while still giving teams freedom
• Geo-load balancing and failover
• Taking lessons learned with resiliency in one Cloud Foundry deployment and applying
globally across several
17. Importance of Monitoring
• We quickly learned that you can’t run a microservice-based system without monitoring
• Lots of things can go wrong
• Root cause determination can be difficult
• Examples of needed metrics:
• Data for every inbound/outbound request for every microservice
• Response time
• Response code
• Memory usage, CPU usage, and uptime for every microservice
• General health of ourselves and dependencies
• Synthetic page load data with Sitespeed.io & WebPageTest
18. Global Console: Geo Load Balancing and Failover
• Global Console Phase 1 went
live in Summer 2017
• One global URL
(console.bluemix.net)
• UI region switcher filters the
view rather than redirect to
different URL
• Use Dyn geo load balancing to
serve UI from the nearest
healthy region
• If healthcheck in a region shows
a problem, Dyn routes to the
next closest healthy region
• Odds of all four regions being
down at the same time much
less than one region being down