failed: connection timed out (connection timed out)
ERROR 시각 RMI TCP Connection(89317)-1.2.3.4 com.common.api.ApiSender API 발송중 예외가 발생했습니다. URL : http://1.2.3.4:7070/blazeds/api/캐시갱신, DATA : null
org.apache.http.conn.HttpHostConnectException: Connect to 1.2.3.4:7070 [/1.2.3.4] failed: Connection timed out (Connection timed out)
connection refused는 IP는 연결, port 연결 안된경우이고
Connection timed out인경우는 대부분 서버 방화벽을 막아 버린 경우가 대부분이라고 한다.
여기서
- Conection time out
이란 클라이언트가 서버측으로 connection을 원하지만 서버와 연결이 안될때 발생한다.
클라이언트의 OUTBOUND, 서버 측의 INBOUND 방화벽을 확인해야한다.
Connection Refused
클라이언트가 IP와 포트를 이용해서 커넥션을 요청했는데 이 요청이 들어간 서버에 해당 포트번호를 Listen하는 서버가 없다는 뜻이다.
원인 1 : 클라이언트에서 IP나 포트를 잘못 알았다
클라이언트에서 IP와 포트를 확인.
원인 2 : 서버프로그램이 내려갔거나 재기동중이다
서버 프로그램이 기동되어 있는지 확인.
Connection Timeout
클라이언트가 1번으로 서버에 커넥션을 요청할 때에는 커넥션 타임아웃을 설정해 둔다.
커넥션 요청을 보낸 후에 커넥션 수락을 얼마동안 기다릴지 정해 두는 것이다.
어딘가에 문제가 생겨 커넥션 수락이 오지 않을 경우에 프로그램이 대기상태에서 영원히 멈춰 있을 수는 없으니까. Connection Timeout은 정해진 시간까지 커넥션 수락이 오지 않아서 발생한다.
원인 1 : 방화벽에서 커넥션 요청을 먹어 버렸다
연결하려는 서버의 포트에 방화벽이 설정되어 있고, 클라이언트의 IP가 허용되지 않은 경우에 커넥션 요청이 방화벽에 막혀서 서버로 전달되지 않는다. 이런 경우, 아무리 기다려도 커넥션 수락이 오지 않아 커넥션 타임아웃이 발생한다.
커넥션 타임아웃이 발생하는 거의 대부분의 경우는 이것이 원인이다. 그러니까, 방화벽부터 확인해 보자.
원인 2 : 서버가 너무 바빠서 커넥션 요청을 받기 힘들거나 요청을 받았어도 수락 응답을 줄 수가 없다
아주 가끔 서버에 요청이 몰리거나 문제가 생겨서 서버의 리소스가 거의 남지 않은 경우에 발생한다.
서버의 리소스를 확인해서 커넥션 요청을 처리할 수 있는 상태인지 확인해 보아야 한다.
원인 3 : 커넥션풀의 커넥션이 모두 사용중일 경우
원래 커넥션풀의 커넥션이 부족할 때는 이런 오류가 나면 안 될 것 같은데, 가끔 커넥션풀에서 이런 오류를 리턴하는 경우가 있다.
커넥션풀의 사용가능한 커넥션 갯수를 확인해서 이 값이 0이면 커넥션풀이 원인일 수 있다. 이 커넥션풀의 커넥션을 사용하는 프로그램 중에 수행시간이 오래 걸리는 프로그램이 있다면 문제를 해결해야 한다. 모든 프로그램이 문제 없으면 커넥션풀의 크기를 늘려야 한다.
Read Timeout
커넥션이 수립된 후에 클라이언트가 서버로 요청데이터를 전송한다. 이때에도 서버로부터 응답을 받을 때까지 얼마나 오랫동안 기다릴지 설정하는 것이 Read Timeout이다. 클라이언트가 요청데이터를 보낸 후 이 시간동안 서버로부터 응답데이터를 못 받으면 이 오류가 발생한다.
원인 1 : 서버에서 요청데이터를 처리하는 데 시간이 오래 걸린다
서버에서 요청데이터를 처리하다가 시간이 너무 오래 걸린 경우이다. 처리 프로그램에 문제가 있어서 오래 걸릴 수도 있고, DB에 요청했는데 SQL이나 인덱스, 락 등의 문제로 응답이 오지 않거나 다른 서버와 인터페이스 중에 응답이 안 오는 경우가 있다.
서버프로그램의 처리상태를 확인해 보아야 한다.
원인 2 : 서버프로그램의 대량데이터 조회
조회조건 등의 문제로 서버프로그램이 조회한 데이터를 응답데이터로 만들기 위해 가공하는데 시간이 오래 걸릴 수 있다.
조회조건 등을 제한해서 지나치게 많은 데이터가 조회되지 않도록 해야 하고, 대량데이터를 조회할 수 밖에 없는 상황이라면 클라이언트의 Read Timeout을 늘려 주어야 한다. 대량데이터를 처리하기 위해서는 많은 메모리가 필요하므로 OutOfMemory가 발생하지 않도록 메모리도 늘려 주어야 한다.
원인 3 : 네트워크 대역폭
아주 드물게 서버에서 클라이언트 방향으로 네트워크 대역폭이 좁은 경우, 네트워크를 통해서 응답데이터가 오는 데 시간이 오래 걸릴 수 있다.
아주 드문 경우이지만, 이런 경우도 고려해 볼 필요가 있다.
Too Many Open Files
파일을 열 때 뿐만 아니라, 네트워크 클라이언트 프로그램이 소켓을 열 때도 File Descriptor를 사용한다. 즉, 네트워크 소켓이 허용된 것보다 많이 열려고 시도하면 위와 같은 오류가 발생한다.
일단, 현재 열려 있는 파일과 소켓을 보고 싶으면 lsof나 pfiles 명령을 이용해서 확인할 수 있다.
원인 1 : ulimit의 open files 값이 너무 작다
open files 값이 1024와 같이 너무 작으면 기본적으로 열 수 있어야 하는 파일과 소켓을 열 수 없어서 오류가 발생한다. ulimit 명령을 이용해 충분히 수용 가능한 값으로 설정해 준다.
원인 2 : 파일이나 소켓을 연 후에 닫아 주지 않았을 때
파일이나 소켓을 연 후에 닫지 않으면 open files의 값을 계속 잡아 먹게 된다. 이런 것들이 쌓이게 되면 어느 순간 Too Many Open Files 오류가 발생하면서 더 이상 파일이나 소켓을 열지 못 하고 서버가 멈춘다. 열면 꼭 닫는 버릇을 들여야 한다.
원인 3 : 짧은 시간 안에 지나치게 많은 소켓을 열었다가 닫았을 때
아무리 소켓을 열었다가 사용 후에 잘 닫아도 프로토콜(특히 HTTP)에 따라서 실제로 커넥션이 OS단에서 끊기는 데 시간이 걸린다. 그러니까, 프로그램에서 소켓을 닫아도 어느 정도 후에 실제 OS에서 커넥션이 끊기므로, OS에서 실제로 끊기지 않은 소켓이 많이 쌓이면 이런 오류가 발생할 수 있다.
이런 일을 방지하기 위해서 커넥션풀을 사용한다. 커넥션 생성에 필요한 시간과 리소스사용을 줄일 수 있고, 끊길 때까지 대기하는 커넥션이 쌓이지 않기 때문에 이런 오류를 방지할 수 있다.
출처: https://romainefabula.tistory.com/87 [로메인의 설방:티스토리]