Microservices have changed the way we build applications. Software design has moved from large monolithic applications (which are not really adaptable to changes and improvements) to a collection of small, independent processes infrastructure which is far more suited to adapt to changes in today’s agile world.
How Do Microservices Communicate?
Microservices are decoupled from each other, but still have to be able to communicate. When it comes to managing communication within a microservices infrastructure, one of the most popular methods is asynchronous communication.
While synchronous communication requires waiting for a response before moving to other tasks, asynchronous communication gives us the flexibility to send a message out between the microservices and continue working on other tasks. This approach also increases the independence of every microservice – in case of a microservice outage, the other services will not be impacted since the task will be on hold until the failed microservice will be up and running again. One of the best examples of asynchronous communication is emails. After an email has been sent, the sender can continue working on other things while the receiver is able to read the email, knowing that the sender is not dependent on a reply to continue their work.
Implementing asynchronous communication can be achieved by using a Message Queue – temporary storage for all messages waiting while the destination service is busy or unavailable. The basic architecture of message queueing is pretty simple, there are producers and consumers. Producers are the applications/services that create messages and deliver them to the queue. Consumers connect to the queue and get the messages to be processed.
In order to implement message queueing, we need a message broker – a service that receives messages from the producers and hands them over to the consumers. Messages are not published directly to the queue. Instead, the producer sends the messages to an exchange, which routes messages to different queues. The messages stay in the queue until the consumer handles them and removes them from the queue.
JFrog Xray Example
JFrog Xray has 2 main working flows:
- Database Synchronization – Retrieving data on issues and vulnerabilities automatically on a daily basis from a global vulnerabilities database server maintained by JFrog, including data from premium resources such as VulnDB. Also enables a manual offline mode for air-gapped/DMZ environments.
- Indexing Resources – Indexing and matching violations and vulnerabilities to components within the indexed resources.
This flow is divided into 2 flows – new content and existing content.
In Xray, all internal communication between microservices is asynchronous and managed using a RabbitMQ message broker.
Note: Already working with JFrog Xray? Read this article to learn more about RabbitMQ in JFrog Xray.
How JFrog Xray uses RabbitMQ
Xray has multiple crucial roles, such as scanning, impact analysis, and database sync. These roles require simultaneous flows to be processed by the different Xray services. Xray uses RabbitMQ to manage these different flows while tracking communication between services.
RabbitMQ manages 3 main types of queues in Xray:
- New Content – Responsible for events related to new content added to the system. For example, uploading a new Artifact to a repository that is marked for indexing -> will create a message in the Index queue.
- Existing Content – Responsible for the content which already exists in the system. For example, reindexing a repository will send messages to this queue.
- Retry – Failed messages will be sent to this queue and will stay there for a TTL.
Once the TTL has elapsed, the messages will be returned to the original queue.
The queue names are defined by the service name and the queue type (new content queues name do not have any suffix). For example – ‘indexExistingContent’, and ‘alertRetry’ while ‘persist’ has no suffix. This naming convention is useful when debugging RabbitMQ queues since the queue name is predictable.
JFrog Xray queues in Xray’s main flows
This approach of separating the workflows into independent queues is helpful with reducing the load on the messages queue and providing a more fluent functionality.
Every Xray microservice has a configurable number of consumers called “Workers”. Scaling up the workers can be done by increasing the number of workers for specific queues or adding new Xray instances to the cluster. Tuning the number of workers for each service individually provides the ability to optimize Xray’s performance by assigning fewer workers to less intensive services and utilize the instance resources where it’s needed more.
Try it out
JFrog Xray maintains its internal microservices asynchronous-communication using the RabbitMQ message broker giving it better robustness and scalability.
Want to experience this independent and asynchronous communication-based software while improving your DevSecOps? Start using Xray for free >