How to handle "io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer" in WebClient Springboot
Asked Answered
R

0

6

I had 579,000 pending messages in my ActiveMQ, and I needed to publish these messages to a REST API. While doing so I was hitting the REST API at the rate of 3000 hits/second asynchronously. After some time I started getting the below mentioned exception continously for every request:-

2021:06:10 05:25:40.002 [DefaultMessageListenerContainer-58047] [INFO] [com.main.consumer.AmazonMQConsumer] - Recieved TOPIC MESSAGE: DUMMY_MSG
2021:06:10 05:25:40.004 [reactor-http-epoll-6] [WARN] [reactor.netty.http.client.HttpClientConnect] - [id: 0DUMM895fb, L:/DUMMY_IP:DUMMY_PORT - R:DUMMY-URL.net/DUMMY_IP':DUMMY_PORT'] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
2021:06:10 05:25:40.173 [reactor-http-epoll-7] [WARN] [reactor.netty.http.client.HttpClientConnect] - [id: 0DUMMf5600, L:/DUMMY_IP:DUMMY_PORT - R:DUMMY-URL.net/DUMMY_IP':DUMMY_PORT'] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
2021:06:10 05:25:40.365 [reactor-http-epoll-9] [WARN] [reactor.netty.http.client.HttpClientConnect] - [id: 0DUMM9223f, L:/DUMMY_IP:DUMMY_PORT - R:DUMMY-URL.net/DUMMY_IP':DUMMY_PORT'] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
2021:06:10 05:25:41.966 [reactor-http-epoll-8] [WARN] [reactor.netty.http.client.HttpClientConnect] - [id: 0DUMMb5cf1, L:/DUMMY_IP:DUMMY_PORT - R:DUMMY-URL.net/DUMMY_IP':DUMMY_PORT'] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
2021:06:10 05:25:43.419 [reactor-http-epoll-8] [WARN] [reactor.netty.http.client.HttpClientConnect] - [id: 0DUMM7fa0a, L:/DUMMY_IP:DUMMY_PORT - R:DUMMY-URL.net/DUMMY_IP':DUMMY_PORT'] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
2021:06:10 05:25:43.419 [reactor-http-epoll-8] [WARN] [io.netty.channel.AbstractChannelHandlerContext] - An exception 'reactor.core.Exceptions$ErrorCallbackNotImplemented: reactor.core.Exceptions$RetryExhaustedException: Retries exhausted: 3/3' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Request to POST https://DUMMY-URL.net/api/v1/evt?p=.....so on
    Stack trace:

Asychronous Rest API call code:-

@Service
public class DummyConnectionService {
    @Value("${web.client.retry.max-attempts}")
    private String maxAttempts;
    
    @Value("${web.client.retry.min-backoff}")
    private String minBackoff;
    
    @Value("${Dummy.base-url}")
    private String DummyBaseUrl;
    
    @Value("${Dummy.api-path}")
    private String DummyApiPath;
    
    @Autowired
    WebClient.Builder webClientBuilder;
    
    public Mono<String> sendDataToDummy(String query, final String eventData) throws Exception {
        Mono<String> response = webClientBuilder.baseUrl(DummyBaseUrl)
                .build()
                .post()
                .uri(uriBuilder -> uriBuilder
                        .path(DummyApiPath)
                        .query(query)
                        .build(eventData))
                .retrieve()
                .bodyToMono(String.class)
                .retryWhen(Retry.backoff(Long.parseLong(maxAttempts), Duration.ofSeconds(Long.parseLong(minBackoff)))); //maxAttempts = 3, minBackoff = 5
        
        return response;
    }
}

Calling code for sendDataToDummy():-

Mono<String> response = DummyConnectionService.sendDataToDummy(postData.toString(), json);
            
response.subscribe(res -> {
    if(res.contains(STATUS_OK)) {
        log.info(res);
    } else {
        log.error(res);
    }
});

Kindly help me by letting me know why such exception is coming and how to handle it gracefully without halting program flow.

Ringnecked answered 10/6, 2021 at 3:59 Comment(7)
Maybe your server REST API is not able to handle these many calls. Did you try something like JMeter to verify if it can handle so much traffic?Calcariferous
JMeter, no I didnt, actually its some other vendor's apiRingnecked
Before writing anything on top of any other vendors API, just do a performance testing and verify if it's able to handle that much traffic or not.Calcariferous
Sure, so @RamanSahasi are you suggesting that the exception has occurred due to some problem from the server end? if so, then please provide your insights on what issues on server can cause this exception and please help me by letting me know how can I improve my code to handle the exception gracefully.Ringnecked
yes I believe that it's highly plausible that exception is because the server is not able to handle that many requests. I recommend you to find how much traffic your server can handle and limit your number of requests per second to that limit. Additionally, you can also implement circuit breaker to make sure that you're not hitting the server continuously when the server is down. This is just a suggestion in case you're making a lot of calls parallelly.Calcariferous
However, for your case, I'd recommend looking at Exception handling with spring webclient to handle your exceptions gracefully.Calcariferous
i have same exception and no any call on the serverCurfew

© 2022 - 2024 — McMap. All rights reserved.