1

I'm currently working on a project which is build as a microservice architecture.

We have one "Gateway" which aggregates the data coming from the different microservices to return one aggregated result to the frontend. The "Gateways" exposes GraphQL queries and mutations to CRUD data.

The microservices are build using java and spring boot and expose several REST API endpoints.

The problem I'm currently facing happens when it comes to generate a aggregate report.

For example:

  1. Fronted queries all orders within a time span
  2. Orders microservice returns a List of orders containing a list of products and a customer reference
  3. Now for each product in one order a GET to the product micro services is invoked to get the product data. That means if an order contains 10 products 10 GET requests are created to get the data.
  4. Same goes to the customer reference. A GET request is invoked to get the concrete data of the customer from the customer micro service

Now if we imagine we want to query all orders of the last month this ends up in a long-running query which might run in a timeout.

I know that microservices in general do not claim to be fast and that this is not their main purpose. But the current situation is not sustainable.

Are there any ideas to improve the performance without re-implementing the whole project?

Sorry if this is the wrong stack network for such questions.

4 Answers4

4

One way to 'solve' this is by re-designing or extending the REST interfaces to support batches next to single item requests.

E.g.:

Next to the GET server/products/314 you could implement a POST server/products/filter and post a body containing the ids of multiple products.

This would reduce the number of round-trips (assuming that these are the costly part of the current design)

Emond
  • 1,258
2

We can probably redesign the Order Microservice to store and return a tailored amount of Product data along with Product reference (same for Customer data), which is needed for "Order Summary" view/response; It's not very uncommon to have same data residing in multiple systems, especially since this by nature is mostly static (i.e. Ordered Product details won't change post-Order) and need not be updated for a change in Source system; So a sync-up of this data with it's Source-Of-Truth ideally may not be needed..

Product reference can be used to fetch individual Product details from Products microservice based on further User action for fetching individual Product(s);

Divs
  • 187
0

This is reminiscent of historic code: queries and then loops inside loops doing queries themselves.

Move the frontend methods with heavy microservice usage to the backend. Then there the prior microservice calls can be immediate calls, and all in the same transaction.

This kind of refactoring can be done step-wise, parallel to the working system.

Such batch services require some care, as you pass larger data object models. A version in data and code for maintenance of the data, especially if more than one team is involved. JSON might be an easy readable format, but there are binary formats too (Hessian, ASN defined). Binary data has one advantage: no conversion back and forth. If versioned, no problem.

The data model can be optimized for streaming, so that I/O can immediately start. In order of the queries, and the queries in order of the front end usage. This should be realized in a special kind of Test Driven Model, testing such transfer of the data only, listing it in text for comparison; a long developed unit test.

Joop Eggen
  • 2,629
0

In principle, each logical set of data should have its own microservice that has exclusive access to that data (encapsulation). However, sometimes it cannot be avoided to have a complex query on multiple sets of data implemented in one service, for performance reasons. In most relational database systems, you can define a 'view' to decouple the query from the physical database structure.

You could extend the REST interface to generate a report by one 'microservice' in one call. Design a URI for the report, e.g. mydomain.xx/reports/orders and then use http method GET on this URI to let a special reporting service generate the report.