— 6 reading minutes
It is no longer the latest trend, now we should be talking about Blockchain, Machine Learning and things like that, but not so long ago microservices were what was on everyone's lips, everyone was moving monolithic applications to microservices, microservices had arrived to save us from all the evils of software.
Obviously, this was not the case, one thing for another, there are still many things that can be improved in the world of software, but although they are no longer used for everything and do not always make sense, microservices are here to stay, and in this post we are going to try to explain for humans what they are, and ways to implement them in Google Cloud.
If you follow our blog regularly, you will see that we have already written several articles with terminology for humans, with which we aim to bring technology closer to everyone:
What is a microservice?
The first thing to explain is that microservices arise as an approach or methodology for software architecture. Before microservices were monoliths, pieces of software in which all the parts were contained in the same architecture; if one part needed to grow because demand increased, the entire infrastructure had to increase. Also, if new functionality had to be added to a part of the system, when delivering the software the entire monolith had to be delivered, not just the piece corresponding to the new functionality, and so on.
A microservice is an independent software component that usually encompasses a complete functionality, however small it may be (hence the name micro) and that offers an API to the rest of the software pieces to communicate with it. The independence of the microservice is also usually at the hardware level, so that if the demand for a particular service increases, only the infrastructure for that service will have to increase.
The development of the cloud, access to infrastructure or platforms as a service, has helped a lot to facilitate architectures based on microservices, because this separation at the level of resources per service is much easier to configure and set up in the cloud than if we have to worry about all the hardware ourselves. The rise of the IoT or Internet of Things, with complex networks of sensors sending information to be processed, has also greatly encouraged its use.
Ways to run microservices on Google Cloud
As we have said on other occasions, in Google Cloud there are multiple ways to execute the same project, largely depending on whether we want to manage the infrastructure ourselves or delegate management to Google itself. This is the case of a Kubernetes cluster with microservices, which we can do both on desktop machines and on the cloud. Compute Engine directly, or with a cluster managed with Google Kubernetes Engine (GKE).
The first case is the closest thing to having the machines anywhere and managing the Kubernetes cluster (more on this in Kubernetes for humans ), only that they are virtual machines, we do not have to worry about whether the power supply dies or the fan makes noise, etc., but both the installation and maintenance of Kubernetes would be on our own, in the second case it is a cluster managed by Google.
For this reason, in these cases we are always aware of the existence of the machines on which these microservices are running, the number of nodes, and their location. In the case of creating the cluster ourselves with Compute Engine, we are directly responsible for adding more machines to the cluster if necessary. If we want to completely abstract ourselves from this, we can run the containers directly on Google's infrastructure with Google Cloud Run and forget us whatever infrastructure is underneath. I put forget in italics because although it is true that we will not know which machines are running our code, that is partly the point of Google Cloud Run, we do have to define the infrastructure model, the amount of resources we want them to have available, etc. This will be the case in the rest of the cases as well, with App Engine or Cloud Functions, let's say that it is our responsibility to define what type of machine we need and what scaling, if we want them to scale automatically.
The difference between the last three solutions is that in the case of Cloud Run we will directly deploy container images, in AppEngine if what we are going to execute is code in Node, Ruby, PHP and a series of standard languages that Google supports, we will have native containers already prepared and we do not have to worry about creating the container, only the code and writing an app.yml file with the configuration.
With Cloud Functions the differences increase considerably. In Cloud Run and AppEngine, we could have multiple services in the same application/deployment, with Cloud Functions What we are deploying are specific functions, isolated from each other. In fact, each execution of a Cloud Functions function is independent of the rest and they do not share data, so if we need to store anything we will have to do it externally or in Cloud Storage files. Cloud Functions are perfect for performing very simple tasks of extracting information from a database, for example, processing it and saving it elsewhere, or transforming files. As they can be launched following an event, Cloud Functions are also perfect for linking to event queues Pub/Sub Here are a series of examples taken from the Google Cloud documentation, but there are endless possibilities:
In this case, the temperature information from a sensor is stored in a pub/sub queue (the sensor is accessed through Cloud IoT Core, which is a platform for managing IoT devices), and from there a Cloud Functions function is triggered that changes the configuration of another device, in this case a fan.
In this case, when a new image is stored, for example in Cloud Storage, we launch a Cloud Function with an event to send that image through an image processing API, Cloud Vision API , and if we detect that there is something offensive in the image, blur it with another Cloud Functions function and store the result back in Storage.
Cost
Obviously, all of the above has a cost, but in our experience, if you choose the right tool for each problem, you can reduce costs considerably. For example, in the last case I mentioned above, if image processing is something fundamental in our application and it will be happening constantly, it may make sense to keep it together with the rest of the functionalities, but in many cases it is something that is expensive to process and that happens only occasionally. If we keep it with the rest of the things, we have to scale everything for those specific peaks. In those cases, taking it out to a microservice, with any of the solutions mentioned, can reduce costs a lot.
I have also mentioned another situation in which it will be very useful, executions of very specific tasks, things that happen once a day or a month, data processing to do a statistical analysis for example and save that analysis in other tables, etc., these executions are perfect in separate functions. This is something that has traditionally always been done with a cron at night , but in international applications with multiple time zones, or when this processing is very computationally intensive, it makes more sense to move it off-site.
Speed in scaling
Finally, and so that this article doesn't end up being too long, another issue that we have noticed with some clients is that if you have everything in the same monolith and it has to scale, the image of the containers is large, the containers take a long time to be raised, the cluster of machines takes a long time to react when there are peaks in demand... the whole system becomes lazy, it's like an elephant trying to be agile, it's complicated. Peaks can be softened with reserve machines, and by scaling ahead of time (lowering the percentages at which to scale), but this of course has a cost.
It is easier, in these cases, to split into separate services and scale them separately, either with smaller containers or by moving some services to Cloud Functions.