The team at lastminute.com rearchitected the search result aggregation process by breaking up the single service into multiple ones and introducing asynchronous integration. Developers used RabbitMQ for messaging and Redis for storing results from data suppliers. The revised architecture improved scalability and deployability and reduced resource utilization.
lastminute.com platform uses third-party suppliers in the travel solution search aggregation process. Historically, a single Java component called the Transportation Supplier Aggregator (TA) encapsulated the entire aggregation process. Specifically, the component would internally spawn many threads to execute HTTP POST requests to data supplier systems and subsequently collect and process the results when available.
The Initial Search Result Aggregation Architecture (Source: lastminute.com Technology Blog)
The team at lastminute.com determined that the existing architecture of the aggregation process suffered from numerous issues, including high coupling, poor scalability, deployment complexity, and high resource utilization. Giuseppe Pinto, product engineer at lastminute.com, explains resource utilization challenges observed in the architecture:
This system had to handle approximately 50 million requests per day [...], which means around 600 requests per second (calculations were made on days with no particular traffic; however, in certain circumstances, the numbers can even double). Notably, every individual request led to the generation of N+1 threads to fulfill the system’s goals. Each of these threads was responsible for handling complete responses from the suppliers, which, in certain instances, consisted of travel solutions encapsulated within an HTTP response of 25 megabytes. In summary, it was highly resource-intensive in terms of both threads and memory usage.
The developers opted to break up the TA service and move data provider integration logic into independent microservices while leaving the TA service to focus purely on orchestration and result aggregation. The new architecture introduced RabbitMQ as a messaging service that is used to dispatch search tasks to data provider search drivers and deliver task completion notifications from search drivers back to the aggregation service.
The interaction between the TA service and search drivers employs the Remote Procedure Call (RPC) pattern based on a more generic Request-Reply pattern. The pattern requires two message queues. The first one is used for sending search task requests, containing a correlation identifier and the name of the reply queue. The second queue delivers search task completed notifications containing the correlation identifier from the search task message. The aggregation service tracks pending search tasks and uses the correlation identifier to match up dispatched search tasks and received completion notifications.
The New Search Result Aggregation Architecture (Source: lastminute.com Technology Blog)
In the new design, search driver services don’t include travel solution data returned by the data supplier in the notification messages sent back to the TA service. Instead, they store the data in a normalized form in the Redis cache, and the TA service fetches these from Redis once all search completion notifications arrive.