Microservices Gone Wild – Tech Dive Part 3

Tech Dive - Microservices

In this third post in the series about microservices, I’ll finish building my main application so that I can demonstrate a microservices-based application in action, albeit for a very basic set of functions. This post may be a little go-heavy in places, but bear with it and I’ll get to the demo soon enough. It doesn’t really matter what language is being used; I just used go because it’s good practice for me.

Building The Main Application

As a reminder, the main application will need to accept two numbers on the command line then will need to multiply the two numbers and then square that product. The two mathematical functions (multiply and square) are now offered via a REST API, and each one has its own separate Docker container with apache/PHP to service those requests.

I have created hostnames for the two microservice containers (DNS is the only smart way to address a microservice, after all) and they are accessed as:

  • multiply.userv.myapp:5001
  • square.userv.myapp:5002

The API path is /api/ followed by the name of the function, multiply or square, and the values to feed to the function are supplied as the query string. Most APIs tend to be written based on objects rather than functions, but for simplicity let’s run with this for now, e.g.:

Finally, I’ve renamed my main program usquariply to indicate that it’s the µService version of the amazing squariply application.

usquariply

May I add my usual disclaimer once more that I am not a programmer? Good, thank you. I am sure I am doing bad and inefficient things here, but the point is to make it work above all else (though I welcome corrections and tips in the comments!). If you’re not interested in the detail, just scroll on by.

Testing The New Application

One quick build later, and I have an executable to test:

That seems to work quite nicely.

Comparing Speeds – Monolithic Versus Microservices

It would be rude not to see which is faster, and I doubt the result will be a surprise. I’ll run five tests of each type to make sure the results are vaguely consistent:

The monolithic app takes roughly 0.06 seconds to run versus an average of around 0.26 seconds for the microservices version, which makes the microservices-based app around 4 times slower than the monolithic application. Clearly though, this is not a representative test for microservices in general. The overhead involved in opening an HTTP session and processing the JSON response by far exceeds the time spent on the calculation itself, so the overhead here represents a larger percentage of the run time than it would with a more complex function. Where a microservice performs a function that is more complex and takes longer to run, overhead as a percentage of the over all processing time decreases, and the numbers will start to look more similar.

To prove this, imagine that our mathematical functions (multiply and square) are in fact terribly complex, and to multiply two numbers will take 2 seconds, and to square them will take 3 seconds. For those of you thinking “But wait, squaring a number is the same as running the multiply service with A and B set to the same value so how can it take a second longer?” can have a gold star and be quiet again while I simulate processing time in both the monolithic and the microservices models by adding in delays:

Monolithic

To add a delay, I add the time module as an import, then use its Sleep function:

Microservices

For the microservice version, I will add the delay in the PHP microservices themselves:

Note that for usquariply, in order to change the behavior of the microservices, I did not have to alter the main application in any way; it was all done within the microservices themselves.

Comparing Speeds – Take 2

Let’s try our new, extremely slow and complex functions. The single measurements shown below show representative values from a number of samples:

This time the microservice is 0.44% slower than the monolithic code, compared to the 400% slower in the original test. So don’t assume that microservices code must be slow.

Add “Deployed Microservices-Based Application” To Résumé

This is all great, but so what? It seems like I’ve had to write a whole bunch more code, I now need three machines (or VMs / containers) instead of one, and I also need to add code to handle delays and failures over the network. This is true, and it’s one reason why microservices are not the right fit for every application, nor for ever dev team. However, maybe there are some other benefits to all of this, and that’s what I’ll look at in the next post.

Be the first to comment

Leave a Reply

Your email address will not be published.


*


 

This site uses Akismet to reduce spam. Learn how your comment data is processed.