In this series of technical readings we aim to describe how we do things here at PortaText, and what kind of technologies we use to provide a high quality service for our customers. For this post we are discussing how we use microservices in our own architecture to enhance the overall client and engineer experience while using and maintaining our infrastructure, and have a lot of fun at the same time!
Microservices are the exact opposite of a Monolithic Architecture. Let’s see how we use them and what kind of benefits we are getting from them.
Micro Services: Divide and Conquer
Let us start by saying that we believe in tackling one problem at a time, and before trying to solve any kind of problem or implement any kind of feature by building complex solutions, we spend a bit of time thinking about how it would be the best way to divide it into smaller pieces, that in the end will end up completing a feature or adding value for our clients.
These small pieces (of code) can communicate to each other, and will usually end up creating an ecosystem of microservices, and each one of these microservices have a very specific mission to accomplish in our services ecosystem.
Perhaps a small billing function, or notifications, or logging, tagging, etc. Sometimes they all form a pipeline where the output of a microservices becomes the input of another one.
Commands and Events
We also have commands and events in our systems, and this means that a user action (for example adding funds to an account) dispatches a command that in turn, may also dispatch one or more events.
Each event or command is handled separately by different services (perhaps handled by several at once) and they act upon those by for example writing audit logs, or sending notifications, or alerts.
The advantage of this approach is that we end up with very small pieces of code that do very specific things, providing an optimal way of testing each microservice and assuring a great quality in our code. Bugs tend to be easier to spot and get fixed rather quickly when they decide to show their ugly face!
As you might have already guessed, we can take some specific microservice and shut it down if we feel there’s a serious failure somewhere, without taking the whole system down.
This means that we can downgrade our service without stopping the whole system, so a failure in a specific microservice will usually not affect other parts of the architecture (unless they are directly related) and that allow us to fix it and upgrade it by deploying new code separately from other services. How cool is that?
Monitoring is also enhanced, since we can monitor different microservices and take any actions needed when something’s up. If we see that a specific microservice is not working as it is supposed to (perhaps a high error ratio, or slow response times, high cpu or memory usage, etc) we can detect it and pinpoint the issue really fast.
Microservices have also a nice side effect, which is that they can scale horizontally. When we see a lot of work getting piled up on a specific service, we just add more workers to process the tasks faster, and then reduce the number of workers when they are no longer needed. We can also do this automatically.
Diversity is fun, it is also great in all aspects of life, it allows one to keep moving and maintain an open mind about different points of view and extend personal growth by taking the best of all worlds.
That’s why we love having a mix of programming languages in our architecture so our engineers can feel comfortable in their language of choice, and microservices make that really easy.
At PortaText we love our job, it is really fun because things can be done in different ways, and extending and maintaining the system becomes really easy since we can focus on one problem at a time, and then work out the possible solutions, discussing different alternatives and technologies that might do the job, and this ends up in offering a great service for our customers, what could be better than that?
— The PortaText Team.