Jsoup TimeoutException

문제

Jsoup을 이용한 웹 크롤링을 하는 도중 TimeoutException이 발생했다.

세 가지 TimeoutException이 랜덤하게 발생했는데 Read Timeout, Connetion Timeout, socket timeout이었다.

  • Connect Timeout: 웹 페이지에 연결하는데 걸리는 시간이 오래걸려 발생하는 예외이다.
  • Socket Timeout: 서버와 클라이언트가 패킷을 주고 받을 때 전송 시간 차이가 생기는데 이 시간의 제한을 socketTimeout이라고 함
  • Read Timeout:  연결은 잘 되었으나 웹 페이지를 읽어오는데 걸리는 시간이 오래걸려 발생하는 예외

검색

해당 예외를 처리하기 위해 검색을 했을 때 가장 많이 나온 솔루션으로 Thread.sleep()을 사용해서 딜레이를 주는 방식과 Jsoup에서 Document를 get할 때 timeout을 길게 세팅하는 방법이 있었다.

하지만 나의 경우에는 해당 방법을 사용했을 때 별 다른 변화가 없었다.

 

원인 분석

문제를 해결하기 위해 고민해본 결과 웹 페이지를 크롤링하고 바로 크롤링한 정보를 DB에 저장하니까 DB 접근 횟수가 크롤링 횟수 만큼 발생하였다. 크롤링해서 읽어오는 페이지 수가 8000페이지 정도 됐었기 때문에 DB 커넥션을 8000번 한다는 것이었다.

 

해결

DB에 크롤링한 데이터를 바로 저장하는 방법 대신 List에 데이터를 저장하고 한번에 저장하는 방식을 사용했다.

이 방법을 사용했을 때 Timeout 발생 시점이 뒤로 늘어나긴 했지만, 여전히 발생했다.

이번엔 8000개의 데이터가 List에 저장되니까 리소스를 많이 잡지않을까? 라는 생각에 Buffer 처럼 일정량을 채우면 비워주는 방식을 사용했다.

8000개가 있다면 1000개 저장하고 List를 비워주고 새로 채워서 저장하는 작업을 반복했더니 Timeout이 발생하지 않았다.