in a galaxy, not that far way…
At work, we have a considerable number of deployables (and yes, i carefully avoid the term µService here). Most of them evolved on top of a home-grown common server framework. While it has its warts, it works.
The Problem is, and probably every engineer with considerable experience knows a situation just like that, has so much detailed, implicit knowledge about the context and processes it is used in, that changing it becomes next to impossible.
So one of my side-track projects became to rebuild this, avoiding its warts, and create a transitional migration path for existing applications and processes. We wanted to help by getting rid of:
- underdocumented features
- hairy lifecycle management
- hard to grasp configuration and stage management
- “well-known”-paths / ports
- home-grown solutions where better alternatives are out there
a new hope
So, with great motivation, and a good feeling of what went wrong the last time, we started rebuilding this. And from a technical perspective, it went well. We built a MicroContainer with proper lifecycle Management, a plugin system, auto-configuration etc. Good stuff. And we progressed quickly.
Of course, in order to be accepted by the average application developer, it is necessary to provide a superset of functionality, compared to what is in place right now. Once you take something away, people start complaining.
This is why a compatibility layer and migration path from the existing framework is so important.
the empire strikes back
But the closer we got to provide a compatibility layer or change the existing processes, things became difficult. Turns out that changing the processes is a challenge for people involved and staying compatible for a reasonable time complicates things a great deal. Same is true for “features” of that framework people/systems rely on. Take monitoring for instance, it might turn out to be pretty hard to stay compatible, if you structurally want to change stuff that goes beyond changing output formats.
And finally, you might realize that things that seem weird from far, are there for a reason. Not necessarily a good reason, but still a reason that makes it hard to change or replace.
Suddenly, you start questioning the value of removing those warts, given that the cost of rebuilding keeps rising where the certainty of acceptance starts to decay.
But wait, it gets worse. Way worse, indeed.
clouds of endor
Now that we rebuild the foundation of what our deployables look like, of course, we want to be future proof. Our way to the cloud is inevitable, so that we have to make sure, our tiny little framework is up for this. What does this mean? Well among other things there are the usual suspects, that come to mind in no particular order:
- Http-Transport communication
- Server Side Load-Balancing
- Client Side Load-Balancing
- Circuit Breakers
- Service Discovery
- Centralized Configuration
- Reliable Messaging
Of course, we dont’t want to reinvent wheels here by building inhouse solutions for all that, right - that’d be stupid. In order to support those features, we just provide wrappers and automatic configuration for the best-of-breed solutions out there, right? But hey, we built a plugin system for that – and we got a few points covered already (like messaging for instance).
Unfortunately, the levels of work involved in creating plugins for lets say accessing a messaging infrastructure and implementing client-side-load-balancing differ - a lot.
Suddenly, summing up the effort needed to create these plugins, document them properly and maintain them for the next decade breaks the mood.
i am your father
Replacing a home-grown, flaky, hard to maintain and underdocumented software by something that already is out there was the primary driver for our endeavor.
As it turns out, we were about to replace it by something a little less home-grown, hopefully a little less flaky, but certainly expensive to maintain and (given our resource situation) probably underdocumented piece of new software.
We are not in the business of creating a framework to sell, are we?
We really just should not do that! It is wrong by any possible measure.
do or do not – there is no
try soft migration path
It looks like, we’d need a more drastic change. A change that involves less coding and more time for solving business problems. Unfortunately that is not compatible with our goal from above to provide an easy and soft migration from what we have to where we want to be. It also probably needs a big bunch of changes in our processes, if we don’t want to provide adapters and wrappers all over the place.
What if, we change our strategy to adjust our infrastructure and expectations to the solutions being out there instead of the other way around?
And what if, we do not even try to be compatible and have a migration path.
awakens gets recognized
We started building a MicroContainer with proper lifecyle-management, a plugin system and all of these qualities you’d want for a foundation of your services.
But, it is considerably hard to find proper abstractions for, lets say
- service discovery
- configuration management
- HTTP routing
- entity-based persistence
Now if we don’t continue that road, lets have a look if there is a comparable thing out there already.
the Sith-Lord in the room
Surprise! There is. It is called Spring Boot. I did not follow the latest developments in the Spring community for a couple of years. Some of the reasons for that can be found here.
If you look at it, they accomplished exactly what we tried to build: A microcontainer with autoconfiguration capabilities and a bunch of wrappers for the best-of-breed solutions to our current and future needs listed above.
On top of that, it is of production quality, there are a bunch of books and other resources about it and - most of all, people took quite some effort to make using it a homogenous experience.
We might disagree here and there (especially with spring-data), but the effort needed to come up with, maintaining, something better than what spring provides, and the risk of failing to actually deliver something really better – plus the fact that home-grown solutions tend to be unknown to new hires, makes it a rather crazy idea to continue going down that road.
So, we’re all sold to Spring Boot now? Well, for now - maybe.
But much more importantly, now that we have to change lots of processes, tools and habits, lets make sure, we wont have to change them again two years from now.
In order to create a sustainable value, we need to create autonomous, self-contained services and a toolchain around it, that is agnostic, if these were created using spring, rails, vert.x, nodejs or whatever is the dish of the day in two years time is.
That involves using standard tools for standard problems where-ever possible, no matter if Beta-Max is better than VHS. Even if it is sad, get over it!
And it makes us rethink the DRY approach to software development as much as the use of noSQL questioned the normalization of database-models.
Decouple, decouple, decouple - even if that means duplication. 1
– i know
You probably are not surprised. You probably knew all this before.
I must confess, i had to get there. As an engineer, if i see something obviously broken, that causes pain almost every day, i find it hard to resist to fix it – and i seriously doubt, i am the only one.
Don’t get me wrong: if we as an industry had stopped challenging the off-the-shelf-solutions, we’d all still be deploying to websphere with xml deployment descriptors by now.
The question to answer is, should you do it, even if you can?
The lesson for me is: keep an open mind, do not underestimate long-term-cost and stay away from fixing problem, that do not deliver business value in the very-near future.
And be very careful to not get into fights you cannot win.
PS: And even if you can win, think twice if it is worth it. I still think the world would be a happier place, if Linus at the time would have simply used mercurial and shut the ____ up. But that’s just me, i guess…