Non trivial Microservice

Introduction

In the context of Ramses, the project I’m creating in order to fulfil all of the requirements, I’ve chosen to implement a non-trivial microservice. I pitched the idea about the implementation to my teachers and begun developing it out further. My idea about this non-trivial microservice is that the logic of my game requires a game model. Users of Ramses can place comments under these games. Instead of combining both of these microservices into one, I decided to split these into two different Microservices. One which contains the Games, and the other the Comments.

Theory

The most important annex within the scope of scalability is the implementation of a non-trivial microservice. This is a requirement due to the nature of scalability; in order to be able to effectively test the scaling of the microservice containers a load balancing test must be done. Such test would blend very well with a non-trivial microservice.

Why is this an effective strategy? You may wonder.

A game object is requested many times, it would be a waste of resource to also serve comments under those games unless those comments are specifically requested. If the Ramses application had the user base of a popular social media hub, and people create constant comments under games then this service could scale independently. In both cases, splitting apart the micro services into two various components only provides benefits and leverages the cost of hosting such codebase on the cloud.

RabbitMQ Because a game may contain a lot of comments, communicating via REST is unnecessary and may be too slow. The Microservices are stateless, thus using RabbitMQ and leveraging it against the demand of comments makes for a faster application.

Implementation

Instead of serving the requested comment resource through a RESTful call, I instead chose to implement RabbitMQ MessageBus into my back-end components. This would add to the non-trivial aspect of the microservice setup. For more information about RabbitMQ visit the Distributed Data page.

I started out by adding a rabbitMQ sub-module in my Game Microservice. In this sub-module I created the configuration for RabbitMQ. In this I define the exchange(derived from environmental variables) and the Queue’s, as well as a function allowing the microservice to call the getAllComments method from the acquired queue.

I additionally added functions and began following Spring AMQP guides (see: https://github.com/cero-t/spring-boot-amqp-tutorial & https://spring.io/guides/gs/messaging-rabbitmq/ )

private String getAllCommentsQueueName = "getAllComments";

@Bean
public Queue getAllComments() {
    return new Queue(getAllCommentsQueueName, false);
}

I created the same resource in my comment MicroService after making a rabbit sender class, enabling me to convertSendAndReceive from the queue. I cast this to a comment list in my GameService. Initially it was returning a null error, due to the comment-dto I had set up that wasn’t properly doing getters & setters. The IDE didn’t point that this was an issue as reflected classes don’t appear to be implemented in IntelliJ.

I adjusted the GameCollection.java & the interface of this class with a method which returns a list of comments found in the rabbit sender class.

@Override
public List<Comment> getGameComments(int id) {
    List<Comment> comments = sender.getAllComments(id);
    return comments;
}

I made a very similar implementation in my comment microservice. But I failed to realize I required a gameId attribute in the model of this class in order to link games and comments. After implementing this and resolving various issues I started being able to call:

\game\{id}\comment

https://i.imgur.com/5Gxaiqp.png

And here the working proof can be seen working on my deployed environment:

https://i.imgur.com/FFynskW.png

For further validation of the scalability please visit the validation page.