Join us for Code @ Think 2019 | San Francisco | February 12 – 15 Register now Limited availability
By Kyle Brown | Published April 13, 2016 - Updated July 26, 2017
In both the Cloud and Agile programming communities, it seems like everyone is talking about microservices. Other architectural principles like REST have taken the development world by storm, and now microservices are the newest wave to crest. But what are they? And why would a Java™ developer care about them?
In this series, I’ll answer those questions and explain why you’d want to migrate your applications to microservices (Part 1). I’ll delve into data refactoring (Part 2), and lay out a step-by-step method to help you migrate to microservices (Part 3).
In Martin Fowler and James Lewis’s classic article on the subject, we have the simplest definition of a microservices architecture: “An architectural approach that consists of building systems from small services, each in their own process, communicating over lightweight protocols.” A critical concept to understand is that each microservice represents one unique business function.
Fowler also refers to microservices as “service orientation done right.” As Fowler and Lewis state, and many others have attested to, the enterprise computing landscape is littered with the remains of large-scale SOA projects gone bad. Microservices may help reverse that trend, but we have to understand where to apply them, and more importantly, recognize that they are especially effective in projects that aren’t the neatest, coolest thing on the block.
Despite what the folks in Silicon Valley sometimes like to believe, not every application is a green-field. The reality is that enterprises have a lot of existing Java code, and a lot of Java developers. It’s simply not economically feasible to throw away all of that Java code and start fresh with all new runtimes and programming languages.
Instead, it’s better to find the good parts and reuse those in the right framework. That’s why refactoring existing applications into microservices is often the best, most prudent approach to keeping your existing systems running while moving them to a more sustainable development model.
So what do I mean by refactoring? Programming communities define it as “introducing a behavior-preserving code transformation.” That boils down to keeping your external APIs the same while changing the way your code operates or is packaged. Refactoring to microservices would thus mean adding microservices into your application without necessarily changing what it does. You wouldn’t add new functionality to your application, but you would change how it’s packaged and perhaps how the API is expressed.
Refactoring to microservices is not right for every application, and you can’t always do it successfully. But refactoring is worth considering when you can’t throw everything away. The three basic considerations are:
The best place to begin is by revisiting your Java application packaging structure and adopting some new packaging practices before you even start to change your code. In the early 2000s we all started building ever-larger EAR files to contain our logical applications. We then deployed those EARs across every WebSphere® Application Server in our farm. The problem is that this tied each piece of code in that application to the same deployment schedules and the same physical servers. Changing anything meant retesting everything, and that made any changes too expensive to consider.
But now with containers like Docker and PaaS, and lightweight Java servers like WebSphere Liberty, the economics have changed. So now you can start reconsidering the packaging. Here are three principles you need to start applying:
You can see the effect of applying these three principles:
Now that your deployment strategy has gotten down to the level of independent WARs, you can start looking for opportunities to refactor the WARs to even more granular levels. Here are three cases where you can find opportunities for refactoring your code to accommodate a packaging approach that packages microservices independently.
Once you’ve built and repackaged the small services defined in the previous three cases, you’ll want to turn your attention to what may be your hardest problem in adopting microservices: refactoring the data structures that your applications are built on. We’ll examine this challenge more deeply in Part 2 of this series. But there are a few rules you can follow for the simplest cases:
Now you have a taste of what refactoring to microservices is about, and what factors to consider in choosing your approach. The good news is that refactoring your code is not as hard as you may think, and in many cases, it’s actually pretty simple. If you work your way through your code looking for these (relatively) simple cases, you may find that the more complex code sections are actually few and far between.
In Part 2 of this series, we’ll dive deeper into how the structure of your data can affect how you choose to introduce microservices into your applications.
November 15, 2018
November 3, 2018
March 6, 2019
Back to top