Improving async performance between two services

Viewed 24

The title is a bit messy, let me clarify things. I have a microservice A which communicates with microservice B. Both use Spring with Tomcat: A using webflux dependency and B using starter-web dependency.

Microservice B have to perform some operations at database and send the transformed data back to A. Microservice A gets the data from B and perform also database operations.

Both are reactive, using Kotlin Flow. The thing is I'm using WebClient to request data from A to B. And its internal buffer it is probably the cause of the issue.

B is emitting a large number of data to A, lets say 5000 objects. If A does not have the spring.mvc.async.request-timeout=-1 (for tests), it throws AsyncRequestTimeoutException. When set as infinite, microservice A is always processing like 2~4% of messages sent by microservice B. If I log both applications, it shows that B has emitted, for instance, object 1234 and A is processing the object 60.

When microservice B is done, I'm shutting it down (for tests) and I realize that all objects are already at microservice A.

Some code (it will be simplified to question propose)...

Microservice A requesting data to B:

class MicroserviceBGateway() {
    private val webClient = WebClient.create("microservice/b/endpoint/")
    private var count = 0   

    suspend fun getData(inputs: Inputs): Flow<ResponseFromB> = 
        webClient.put()
            .body(BodyInserts.fromValue(inputs))
            .retrieve()
            .bodyToFlow<Map<String, Any>>()
            .map {
                println("{++count} mapping received object from B")
                ResponseFromB(it)
            }
            .onCompletion { println("request done") }
}

Microservice B service:

class DataProvider {
    suspend fun invoke(inputData: Data) = flow {
        var count = 0

        someDatabaseOperation(inputData) //this is a flow
        .collect {
            println("${++count} emitting data to client")
            emit(it)
        }
    }
}

So I'm not sure exactly where is the problem. I commented microservice A calls to database, but it still is processing at a 2~4% rate. So I assume it is not any latency between app and database. The far I went is that it is possibly an internal buffer from default WebClient, but I couldn't go further.

Any suggestions on how improve this processing?

0 Answers
Related