In a respective talk, John Sol (Enterprise Architect, Bottomline Technologies) described a journey of taking a monolithic JEE application and refactoring it into microservices from the perspective of developers, QA testers, production support, and the hosting and operations teams.
This presentation by John Sol was held at GlobalLogic Kharkiv Java Conference on June 10, 2018.
2. Who Am I?
Enterprise Architect at Bottomline Technologies
Technology strategy, processes, and standards across enterprise
Support Paymode-X Business Solutions
3. Legacy Architecture
JEE App Server
EAR
UI and REST
<war>
OLTP
RDBMS
OLAP
RDBMS
Management
and
Monitoring
Thin Client UI Mobile App Other Apps
4. Challenge
Single large code base
Large releases
High testing effort
All functionality shares common lifecycle
Operational
Monitoring and management challenges
Unit of scaling too coarse grain
Agility
Can only move at the speed of the monolith
7. Refactored Monolith Architecture
JEE App Server
EAR
UI and REST
<war>
OLTP
RDBMS
OLAP
RDBMS
Management
and
Monitoring
Thin Client UI Mobile App Other Apps
8. Refactored Monolith
Pros
Better code structure
Higher cohesion/lower coupling
Minimize impact of changes
Better test support
Faster to implement
Less short-term risk
Cons
Doesn’t completely address most of the Challenges
10. Ideal Microservices
Pros
More scaling options
Agility
Monitoring and operations
Cons
High risk
Organization not ready
Long time to implement
12. Hybrid
Pros
Practical
Less risk
Faster to implement
Cons
Shared databases
Too much coupling
Supporting multiple versions
13. Hybrid and Microservices Resiliency
Bulkhead microservices to avoid failure chains and cascading failures
Circuitbreakers to protect application from misbehaving remote endpoints
Active/active support
Cloud resiliency capabilities such as availability zones
Reevaluate consistency models
This is the legacy architecture. I’m sure it’s familiar to many of you. It’s a standard JEE application using servlets, JSPs, Spring MVC, and a few message driven beans. It has couple of relational databases, one for OLTP processing and one for OLAP processing. There are management and monitoring tools to operate the JEE app server and database servers.
The deployment is an ear containing a war that handles both user interaction and rest services.
The app server is clustered for high availability and load balancing.
User sessions are sticky and are pinned to a server.
The legacy architecture worked well for years and made lots of money. But as the business changed and our competitors changed, we needed to modernize it to meet new challenges.
The term “monolith” implies a single large code base. Very few people understand the entire code base. This made it difficult to adequately test, to train new developers, and it made the impact of a bug severe. A new developer that did something as seemingly harmless as updating a rarely used utility class could introduce a bug that could bring down the entire application. There was no good bulkhead to contain failures, so just like the Titanic, a little leak can bring down the entire ship.
Large releases
High testing effort
Ripple effect of change on common code base
Regression testing of all functionality
Common lifecycle
Functionality tends to have different lifecycles, but monolith forces all components into a common release cycle
Operational
Monitoring and management
Some functions are more risky, require closer monitoring
Coarse grain unit of scaling
Replicate the ear
Can’t customize the scaling behavior of individual functions
Agility
So how do we evolve the architecture to address the challenges?
The most important challenges to address were
Being able to separate functionality so that each function could have different SLAs and lifecycles
Being able to prevent cascading failures
Organizational Structure
Conway’s law
Teams were basically organized around the monoliths
Operational readiness
How can hosting team monitor, manage, scale-out, deploy, update, etc.
Team skill set
What skills are available, what do they need to learn
SDLC Processes
What changes if any need to be made to align architecture with processes?
How the systems is decomposed drives how work is planned
This is the first option. It’s taking the monolith and refactoring the application architecture and code structure to make it better.
As you can see, it’s deployment view is the same as the legacy architecture.
We can refactor the monolith to provide better modularity. We could follow SOLID or clean code principles, tighten up testing coverage, ensure we have good code reviews and use static code scans so that everyone follows the application architecture.
This produces a better structured monolith and does make it easier to change parts of the application because of things like using proper abstractions, achieving high cohesion and loose coupling, using composition and inheritance wisely, and all the best practices that you can find to clean up application architecture and code.
Target architecture is always evolving because of business needs and technology evolution.
Target architecture is an aspirational model that guides the evolution of the system
Cloud
Cloud native apps
Cloud Native Foundation
Be able to deploy on multiple cloud providers
Containerization
Docker on Kubernetes
All of these are big topics, but I just want to take one and focus on it to talk through the implications on the target architecture. Focus on Reactive
Taken from the Reactive Manifesto
How to implement backpressure using HTTP?
Akka Streams uses TCP to communicate back pressure