Image courtesy of https://www.pexels.com/photo/green-plant-sprout-113335/

Microservices Architecture — Early Thoughts Before That First Step

Michael Douglass
codeburst
Published in
6 min readMar 14, 2018

--

There is much to consider once you decide to start a Microservices Architecture environment from scratch. Couple this with the fact that I am still learning how the industry defines all of this, it is beginning to overwhelm me. So, I turn to writing to help sort through it all. First, I am looking backward to what I have done in the past. This continues from where I left off in Microservices Architecture — A Journey of Understanding

That Strange Sense of Déjà Vu

In the Real Life Example section of my article, Complexity in Software Architecture: Decompose for Simplicity, I talked about a past project and how we decomposed it for simplicity. Through my recent reading about Microservices, it has become obvious to me that we created this application using some principals of Microservices.

The five listed systems (services) were completely decoupled from one another by what we called the Event Bus. This bus utilized ZeroMQ as the underlying communication system, and I spent a good amount of time writing a Python object layer to provide many of the things you need for a good Microservices layer:

  • Service Registration/Service Location — Built in to the event bus layer was an internal service used to both register yourself as a named service and locate other named services.
  • Request/Response and Publish/Subscribe — Both of the common mechanisms available in a Microservices architecture were available and fully utilized by all services.
  • Multiprocess — While the software itself was written to run on a single machine, we still used ZeroMQ’s ability to communicate over network sockets so that we could expand our application across multiple processes.
  • Transport Independence — At any time the use of ZeroMQ could have been replaced with any mechanism we desired. The abstraction through the Event Bus system made this highly possible.
  • Independent Development — While everything was still kept in a single repository, and we were a single team of three people, we were still able to develop on separate parts of the system with great amounts of autonomy. One developer worked a long time on the upload/download logic of the Sync Engine itself while the rest of us developed the other services.
  • Pure Service Testing — Each service was tested entirely on its own. There was never a need to spin up an instance of another service to test the proper functionality of any single one.

The beauty of the Event Bus system I built was that, to the Python developer on the team, most of the details were hidden by the library. For each event or publish type you wished to send and/or receive, there was a simple definition file in the form of a class which encoded internally the named service responsible and all encoding/decoding needs.

Once the Event Bus was written and the kinks worked out, writing the software using it proved immensely easy. Most of the time you never even thought about it. In the code which worked with the event, you trivially created an instance of the class and asked the Event Bus to send it.

Caveat!

In case a former colleague who worked on the same system reads this, yes we did have to pay attention to deadlock issues since ZeroMQ utilized a single thread to read inbound messages. We did not have the library automatically spin processing onto separate threads; we decided to let smart developers decide what they needed. Specifically: “If what you need to do is fast, just do it; if not, marshal your own darn thread.”

The other caveat was that this Event Bus was the FIRST bit of Python code I had ever written. I had just finished Learn Python The Hard Way shortly before starting, and start I did. Have you ever looked back at that “first code” in a new language or environment and thought, “egads”? Yes, this code was of the egads form.

However, it was a solid rock upon which we built one of my proudest pieces of work. Unfortunately the service is now shutdown and we did not get to continue further developing the desktop sync engine, but I am convinced that what we setup in that project was an architecture that would have kept us going for a very long time.

Back To The Microservices…

Now that we have walked a few moments in my past, I want to contemplate what that means for embarking upon a new Microservices architecture. What are the key capabilities I want to be able to provide to my body of developers?

  1. A means of locating a specific service. Pattern matching seems like the most common approach Microservices supporters recommend, so this means having the ability to supply either specific or aggregated patterns for all available services in the environment to any potential client. There are several ways to do this: A) hard-code aggregate patterns to endpoints; B) provide a service registry which supplies live patterns with endpoints; C) provide a messaging middleman who relays messages to the appropriate endpoints.
  2. A means of balancing load for a given service. Breaking a monolith apart only to force a given service author into a single server, single process environment feels wrong. Services should be able to run in a variety of load balanced manners. Again several methods exist: A) use an actual load balancer in front of your services; B) provide client-side logic to switch between multiple endpoints; C) the messaging middleman can hold that logic.
  3. A means of providing services in various regions. We want to build solutions which are highly available. This is an extension on the ability to locate a service and implies additional ability to try different locations if a first location fails. You could have this as a part of middleman service broker, but the best implementation is to include the intelligence in the client.
  4. A means of documenting services. Ideally, services can be self-documenting in terms of: A) what patterns it supports and B) the network protocol used. Done right, I want to be able to ask a service through a message (e.g. {‘role’: ‘user’, ‘__meta’: ‘interrogate’}) to discover what patterns it handles along with human-readable documentation on each pattern’s use. I will be honest, this is a want and not a need.

My Largest Struggle

A benefit touted broadly by Microservice enthusiasts is the ability to author services in varied languages and environments. The problem with this is that if you put too much of the above functionality into a common infrastructure library, then you are building a barrier to entry of other languages participating in the environment.

If you google for Microservices architectures, you will find many code bases claiming to provide you with the underpinnings of such an architecture; I am always left confused after reviewing each one on how exactly this helps keep the architecture open to the use of other languages and environments. Certainly you use standard protocols for the underlying infrastructure (e.g. service location), but the bar for someone to use a new language is much higher than one that already has a fundamental library to register or locate a given service — the new language person has to write that code themselves.

Forward Momentum

So the question before me is exactly what level of the above items we need and how to build them incrementally so that we can begin taking advantage of a Microservices environment now. In a world where you must start somewhere, my mind is to hard code endpoints and use load balancers as needed. As the environment begins to grow and take on more responsibility, I would envision growing it to being more dynamic and more supportive of more advanced functionality. Implement etcd as a service locator, or something along those lines.

The next part of this series is available and has quite the eureka moment: Microservices — It Takes A Platform — Eureka!

If you have any insight, respond here! Otherwise, I hope this article helped you begin to frame more of the Microservices world in your head. I think my next article will be looking at various pre-made systems and components purporting to enable the creation of Microservices. Until next time!

--

--

Developing code & running servers from the dawn of the Internet. I still enjoy the thrill of learning and am passionate about software architecture. Everywhere!