2014-07-17 3 views
0

저는 몇 달 동안 crawler4j를 사용해 왔습니다. 나는 최근에 사이트의 일부가 돌아 오지 않을 것이라고 생각하기 시작했다. 권장되는 솔루션은 resumable을 true로 설정하는 것입니다. 내가 공간으로 제한되어 있기 때문에 이것은 나를위한 선택 사항이 아닙니다. 나는 여러 번의 테스트를 실시하고 매달림이 매우 무작위 인 것으로 나타났습니다. 90 ~ 140 개의 URL을 크롤링 한 다음 중지합니다. 아마도 사이트라고 생각했지만 robot.txt 사이트에는 의심스러운 것이없고 모든 페이지가 200 OK로 응답합니다. 크롤러가 사이트 전체를 크롤링하지 않았 으면 종료됩니다. 무엇이 원인이 될 수 있으며 어디서부터 시작해야합니까?crawler4j가 무작위로 매달려있는 이유는 무엇입니까?

은 무슨 재미있는 것은 내가 블로킹으로 크롤러를 시작하고 후 상태를 검사하는 동안 루프 점이다

controller.startNonBlocking(CrawlProcess.class, numberOfCrawlers); 

while(true){ 
    System.out.println("While looping"); 
} 

크롤러는 응답하지 while 루프를 중단하지만, 스레드가 여전히 살아있다. 즉, 전체 스레드가 응답하지 않습니다. 따라서 종료 명령을 보낼 수 없습니다.

업데이트 나는 그것이 무엇을 일으키는 지 알아 냈습니다. 방문 메소드에서 mysql 단계의 저장소를 실행한다. 이 단계는 다음과 같습니다.

public void insertToTable(String dbTable, String url2, String cleanFileName, String dmn, String AID, 
     String TID, String LID, String att, String ttl, String type, String lbl, String QL, 
     String referrer, String DID, String fp_type, String ipAddress, String aT, String sNmbr) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException{ 
    try{ 
     String strdmn = ""; 
     if(dmn.contains("www")){ 
      strdmn = dmn.replace("http://www.",""); 
     }else{ 
      strdmn = dmn.replace("http://",""); 
     } 
     String query = "INSERT INTO "+dbTable 
       +" (url,filename, dmn, AID, TID, LID, att, ttl, type, lbl, tracklist, referrer, DID, searchtype, description, fp_type, ipaddress," + 
       " aT, sNmbr, URL_Hash, iteration)VALUES('" 
       +url2+"','"+cleanFileName+"','"+strdmn+"','"+AID+"','"+TID+"','"+LID+"','"+att+"','"+ttl+"','"+type+"'" + 
       ",'"+lbl+"','"+QL+"','"+dmn+"','"+DID+"','spider','"+cleanFileName+"','"+fp_type+"'," + 
       "'"+ipAddress+"','"+aT+"','"+sNmbr+"',MD5('"+url2+"'), 1) ON DUPLICATE KEY UPDATE iteration = iteration + 1"; 
     Statement st2 = null; 
     con = DbConfig.openCons(); 
     st2 = con.createStatement(); 
     st2.executeUpdate(query); 
     //st2.execute("SELECT NOW()"); 
     st2.close(); 
     con.close(); 
     if(con.isClosed()){ 
      System.out.println("CON is CLOSED"); 
     }else{ 
      System.out.println("CON is OPEN"); 
     } 
     if(st.isClosed()){ 
      System.out.println("ST is CLOSED"); 
     }else{ 
      System.out.println("ST is OPEN"); 
     } 
    }catch(NullPointerException npe){ 
     System.out.println("NPE: " + npe); 
    } 
} 

매우 흥미로운 것은 st2.execute ("SELECT NOW()")를 실행할 때입니다. 현재 st2.execute (쿼리) 대신; 그것은 잘 작동하고 교수형없이 사이트를 크롤 링합니다. 하지만 몇 가지 이유로 st2.execute (query)는 몇 가지 쿼리를 수행 한 후 정지하게됩니다. 그것은 예외를 출력하지 않기 때문에 mysql이 아니다. 아마 내가 MySQL에서 "너무 많은 연결"을 얻고 있다고 생각했지만 그럴 수는 없습니다. 내 과정이 누구에게나 의미가 있습니까?

+0

디버거 또는 스레드 덤프. – djechlin

+0

이클립스 이외의 디버깅에는 무엇을 사용할 수 있습니까? 매트를 사용하여 덤프 덤프를 얻지 만 유용하지 않습니다. 이상한 점은 모든 도메인에 영향을 미치지 않는다는 것입니다. 일부 도메인의 경우 문제없이 전체 사이트를 크롤링합니다. – Andy

+1

쓰레드 덤프는 crawler4j가 걸려있는 위치를 알려줍니다. – djechlin

답변

2

finally 블록의 중요성.

crawler4j는 c3p0 풀링을 사용하여 mysql에 삽입합니다. 몇 가지 쿼리 후 크롤러가 응답을 멈 춥니 다. @ djechlin의 조언 덕분에 c3p0에서 연결 유출로 판명되었습니다. 아래처럼 마침내 블록을 추가했습니다.

try{ 
    //the insert method is here 
}catch(SQLException e){ 
    e.printStackTrace(); 
}finally{ 
    if(st != null){ 
    st.close(); 
    } 
    if(rs != null){ 
    rs.close(); 
    } 

}