Four M's of Software Development

Many of us are very good at putting our heads down and cranking out code.  We even are really good at stepping back and thinking about how a particular portion of the system should be designed at a higher level.

Every once and a while, it’s useful to step up even further and think about your software system as a whole and think about the path forward.  One way I’ve been thinking about this lately can be summed up as the four M’s: Monolith, Modularity, Microservices and Monitoring

Monolith

A lot of us are familiar with building a large application.  It starts out as a small web application.  Over time, features are added and the application grows.  Traffic grows and the application is deployed to multiple servers. Before we know it, there’s a large monolithic application running on your cluster.  Doing a release of new code means bringing down the whole thing and deploying a new version.

Somehow, you know that this is not how software development.  You scratch your head and wonder how things got to this point and where to go from here.

Modularity

All throughout your career, you’ve been told that problems should be decomposed.  Break the solution down into small chunks, groups of classes.  Bundle these classes together into a module. Perhaps your monolithic application even does this.  You have one module that does X, another module that does Y.  However, because they’re all in a large application, some modules depend on everything. The boundaries between the modules begin to blur.

Microservices

Remember when UNIX was the big new thing? Okay, maybe you’re not old enough to remember that, even I’m not that old.  Once upon a time, applications were built by stringing together a series of smaller applications, each of which did one thing well.  Somewhere along the way, most of us diverged from this practice.

The good news is that software development is starting to return to it’s roots.  Today, this idea is embodied in the notion of microservices.  These aren’t much different from the small applications of UNIX days of yore.  The idea is to take the SOLID design principles to the application level and build small applications, each of which does one thing well and communicates with other services.

Microservices allow releases to happen incrementally.  Rather than bringing down the entire, monolithic application, pieces of the overall system can be slowly upgraded and tested before the next piece is upgraded.  This makes releases smaller, less risky and reduces your stress level.  In addition, if there’s a problem, it’s usually pretty obvious which application is the problem and debugging the problem becomes much easier.

However, microservices are not without their problems.  With a monolithic application, there’s only one thing to monitor, only one thing to bounce, one thing to debug.  It might be hard to debug, but it’s in there somewhere.  With microservices, you have a whole fleet of applications all running around, doing their own thing and talking with each other.  From an operations point of view, this becomes more challenging.  How do you know what’s running where and is it healthy?

This brings us to the final “M” of software development…

Monitoring

Even a monolithic application has some level of monitoring around it (or should).  Is the site up?  Is it processing requests?  Can it talk to it’s data store?

Microservices require you to raise your monitoring story to a whole other level.  The correct behavior of your system may depend on a sequence of events happening, each handled by a different service.  If one goes down, the whole things falls apart.  So having appropriate monitoring for each service is extremely important.  Not only that, what to do in the case of failure needs to be well defined.  It’s one thing to know that a service is down or having problems.  It’s quite another thing to know what to do about it.  Having well defined processes, documentation and training around each service is critical.  You won’t be able to anticipate every failure, but when one does occur, make sure to document the cause, learn from it, maybe even update code to deal with it better, and tune your monitors to detect the failure the next time.

So how is your application built?  What could you do to make it better?  Is there something you could do to start decomposing things into smaller services?  How do you monitor things now and what would you need to improve?