[Error/Spring/Network] SocketTimeOutException

2024. 11. 15. 18:32Backend/Spring

 
로컬 환경이 아닌 서버에서 실행 중 SocketTimeoutException 이라는 에러를 마주하게 되었다! 데이터를 송수신하는 과정에서 만난 에러였다.  해당 에러를 기억하고, 다음에 동일한 상황을 마주했을 때 해결하고자 글을 작성하고자 한다.
 
😭Error

java.net.SocketTimeoutException:
//이하 생략

 
😂원인
 
Socket 관련 에러 중 Timeout과 관련된 에러도 다양하다. 해당 에러들은 '지정된 시간' 내에 어떤 작업이 마무리되지 않으면 발생한다. 해당 에러로 connectionTimeout, socketTimeout, readTimeout, writeTimeout 등이 존재한다.
 
해당 에러마다 원인이 다르고, 그 원인을 파악하여 코드에 반영해야 한다. 예를 들어, connectionTimeout은 클라이언트가 서버와 연결을 시도하지만, connection이 이루어지지 않아 발생하는 에러이다. 반면, socketTimeout은 클라이언트와 서버는 연결이 되었지만, 데이터를 송수신하는 과정에서 데이터를 보내는 속도가 느리거나 응답이 느리게 되면 발생하는 에러이다.
 
따라서 socketTimeout을 해결하기 위해서는, 데이터를 송수신할 때 소요되는 시간 설정을 늘려줘야 한다. 네트워크 상태가 좋아 송수신이 빠르게 진행된다면 발생하지 않겠지만, 현실은 그렇지 못할 때가 많다.
 
📝해결
 
사용하는 '소켓의 라이브러리'가 어떠한지 일단 파악을 한 뒤, 코드를 추가해주면 좋다. 
(물론 application.yml이나 application.properties에 값을 추가해주고, @configuration을 이용해도 된다!)
 
OkHttp 나 Retrofit2 계열을 사용한다면, 다음과 같은 코드를 builder() 중간에 포함시켜주면 된다.

OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)	//60초
    .readTimeout(60, TimeUnit.SECONDS)		//60초
    .writeTimeout(60, TimeUnit.SECONDS)		//60초
    .retryOnConnectionFailure(true)        
    .build();

 
추가로, readTimeout과 writeTimeout은 다음과 같다.
- readTimeout : 데이터를 읽는 동안 클라이언트가 서버의 응답을 기다리는 시간이 설정된 시간을 지난 경우
- writeTimeout : 데이터를 전송하는 동안 클라이언트가 전송 완료를 기다리는 시간이 지난 경우
 
RestTemplate 이라면, 다음과 같은 코드를 추가해주면 된다.

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60000);	//60초
requestFactory.setReadTimeout(60000);		//60초

 
WebClient 라면, 다음과 같은 코드를 추가해주면 된다.

client.get()
	//중간 생략
    .timeout(Duration.ofSeconds(60))	//60초

 
 
References
1. 타임아웃 : https://tyrionlife.tistory.com/790
2. connectionTimeout과 socketTimeout 차이 : https://tomining.tistory.com/164
3. okhttp : https://stackoverflow.com/questions/40170666/java-net-sockettimeoutexception-in-okhttp
4. RestTemplate : https://eblo.tistory.com/64
5. WebClient : https://velog.io/@cheongha/Webclient-Timeout-%EC%84%A4%EC%A0%95