Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get java.net.SocketTimeoutException with OkHttp?

Tags:

java

http

okhttp3

Here's my configuration:

httpClient = new OkHttpClient.Builder()
        .callTimeout(Duration.ofSeconds(60))
        .connectTimeout(Duration.ofSeconds(60))
        .readTimeout(Duration.ofSeconds(60))
        .writeTimeout(Duration.ofSeconds(60))
        .build();

I have a multithreaded process that uses this client. Few seconds after running I'm getting:

java.net.SocketTimeoutException: timeout
at okio.Okio$4.newTimeoutException(Okio.java:232)
at okio.AsyncTimeout.exit(AsyncTimeout.java:286)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:358)

How is it possible if I configured the timeouts to 60 seconds?

EDIT:
Even adding a custom dispatcher didn't help:

Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(Integer.MAX_VALUE);
dispatcher.setMaxRequestsPerHost(Integer.MAX_VALUE);

TECHNICAL DETAILS:
As opposed to what I've said, I'm running both the client and the server on Linux machines:

Client's machine: net.ipv4.tcp_keepalive_time = 7200
Server's machine: net.ipv4.tcp_keepalive_time = 7200

like image 536
yaseco Avatar asked Aug 08 '19 12:08

yaseco


People also ask

What causes Java SocketTimeoutException?

As you may suspect based on the name, the SocketTimeoutException is thrown when a timeout occurs during a read or acceptance message within a socket connection. Throughout this article we'll explore the SocketTimeoutException in more detail, starting with where it resides in the overall Java Exception Hierarchy.

Why does Java net SocketTimeoutException read timed out?

Root Cause This problem is caused by an environment issue, such as: Server is trying to read data from the request, but its taking longer than the timeout value for the data to arrive from the client. Timeout here would typically be tomcat connector -> connectionTimeout attribute.


1 Answers

You are most likely affected by the socket timeouts imposed by the operating system. Java can't extend them since the sockets are managed by the system. As per this great answer, "Changing TCP Timeouts" section:

Unfortunately since TCP connections are managed on the OS level, Java does not support configuring timeouts on a per-socket level such as in java.net.Socket. I have found some attempts to use Java Native Interface (JNI) to create Java sockets that call native code to configure these options, but none appear to have widespread community adoption or support.

For MacOS you have to look at sysctl net.inet.tcp output and see what are the system limits.

like image 123
Karol Dowbecki Avatar answered Oct 24 '22 11:10

Karol Dowbecki