An introduction to Microservices

Lately has been a lot of debating and hype around Microservices. But what are microservices? Why is there that amount of noise around a term? Hope this introductory blog post can help you understand what is a microservice and introduce you into the topic.

Photo by Glen Carrie

What are Microservices?

Paraphrasing Martin Fowlers in his article about Microservices, “microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API”. Although he’s making a reference to HTTP APIs, it’s not the only mechanism to communicate services, but it’s becoming the most used due to the growing popularity of the web services.

It’s pretty common to see people getting confused about libraries and microservices when reading about it for first time. Don’t worry, it happened to all of us. They are different in that libraries are running in the same process than the main application, and they communicate using in-process function calls. Another common mistake is to confuse an architecture based on microservices with a modular architecture. While they are similar they’re not exactly the same. It’s true that microservices are implicitly modular but it’s false that every modular architecture uses microservices. In fact, most of the modular applications are monolithic.

As developers, sometimes we tend to organize our code around technical features, such as frontend, backend, helpers, libraries, etc. Microservices are organized around business capabilities and that’s why it’s often confused with modules of a modular application. It means each service performs a business feature and inside this service you can organize the code as you desire. You can think in a service as an independent application which is able to run alone and has value by itself.

“Smart endpoints and dumb pipes” — with that sentence microservice community tries to summarize how the application should be structured in terms of communication. The smart part of the application should reside in the services (endpoints) and communication should be done as simple as possible, using REST APIs or message queues, such as RabbitMQ or ZeroMQ. In fact, message queues is the second most used approach for communicating services, especially those ones that run long-time operations or are not high priority. For instance, if a service needs to communicate with another one that just sends emails, message queues are a nice choice.

Pros and cons

Microservice term has been out there for years but lately, as web services grow, it’s going to generate some hype around it. It’s not the ultimate solution for all your application architectures, because of this you should be aware of the pros and cons.

> Evolutionary Design

This is probably one of the biggest advantages of the microservices architecture. As your application grows it’s easy to plug-in new services with new business capabilities. As most of the software applications are business-driven and market changes so fast you will end up loving this advantage.

> Multiple Programming Languages

Every time you start an application you have to decide in which language you’ll build it. Sometimes you choose one depending on your skills and sometimes depending on the best choice for the application in question. As time goes on and your application grows you end up having to stick to the selected programming language and related technologies you chose. Then you realize that some new features will perform better in another language/framework. Or even worst, that technology doesn’t have a library to use with your programming language. Here is where microservices can help a lot. As every service is a decoupled and independent application you can use a different language/technology for each one, depending on your needs. So, for instance, your application is written in Ruby on Rails and you want to integrate a chat using Node.js.

> Multiple Database Types

Similarly as described before, you can have different types of database in your application. For instance, let’s say your application uses MySQL to handle most of the relational data but for a chat you may prefer to use a time series database such as InfluxDB. I’m not a DB expert, don’t take my word literally on which kind of DB is the best for a chat, it’s just an example.

> Independent Deployable Units

As I said before, a microservice is an independent application and, as such, it can be deployed independently. It means that every time you need to change a service it’s not necessary to re-deploy the entire application. It will make you feel more self confident when you’re about to deploy.

> System Resilience

As a decoupled and distributed system, when some of the services fails (and it will do) just a feature of your application will fail, but the application will be still usable. Moreover, you can have a service monitoring the rest of the services and if one of them fails it will reboot the service.

> Easy to Scale

Imagine your application is allowing to upload images and apply effects over them. Some of these effects may consume a lot of memory and you don’t want it to affect to the rest of the application. Using microservices you can easily add memory (or other resources) to the server/process running this service. It’s easy to scale resources depending on the service needs.

> Deal with Too Many Services

When you’re deciding in how many services you want to split your application it’s easy to get crazy with the service boundaries and end up having lots of services you’ll have to develop and maintain. It will be so easy to introduce unnecessary complexity into the system, and therefore errors. Be careful with that.

> Code Duplication

The same way is nice to have the ability of using different programming languages, it’s also very easy to have the same code in different languages. When it happens within the same language some people suggest to use this code as a library but then you’ll be introducing coupling.

> Testing

Testing is a pro and a con. While it’s fairly easy to test a single service it can be a pain to test the whole system and its integration, since every time you want to test the entire application you have to configure and set every service up.

> Asynchronicity

Asynchronous operations introduces complexity in its coordination and make it really difficult when you need synchronous or transactional operations.

Many of these are not really a disadvantage but just a lack of tools for automating or monitoring. As a friend of mine says: “We need a tool!”.

Should I be using Microservices today?

That’s a great question I often heard. I would start by analyzing the application needs carefully. My advice is that it’s better to start small and easy but without disregarding that your application can grow and you don’t want to suffer it, but enjoy it. Be pragmatic not dogmatic. It’s true that there are well known practices that will work for your application but don’t be afraid to adapt them to your needs.

A common approach that I also follow is to start the application monolithic but modular. After this, start separating these modules into services as you really need it. It will not be easy, as every in-process call you made you’ll have to rewrite as a Remote Procedure Call, you’ll need to mount a new server/process with its own resources and configure them, but believe me, it will be easier than having to start with a tightly-coupled application.

Form Follows Function

This title is an excerpt of a nice quote from Louis Sullivan:

“Whether it be the sweeping eagle in his flight, or the open apple-blossom, the toiling work- horse, the blithe swan, the branching oak, the winding stream at its base, the drifting clouds, over all the coursing sun, form ever follows function, and this is the law. Where function does not change, form does not change.” — Louis Sullivan

***
by Francisco Méndez Vilas
Full Stack Developer at Redbooth

References

Leave a Reply

Your email address will not be published. Required fields are marked *