2012-01-17 5 views
0

내 html-scraper에 문제가 있습니다. Html-scraper는 HtmlUnit을 사용하여 Java로 작성된 멀티 스레딩 응용 프로그램입니다. 기본적으로 128 개의 스레드로 실행됩니다. 즉, 그것은 다음과 같이 작동합니다 : 큰 텍스트 파일, ping url에서 사이트 URL을 가져 와서 액세스 할 수 있는지 - 사이트를 구문 분석하고, 특정 HTML 블록을 찾고, HTML 코드를 포함한 모든 URL 및 블록 정보를 데이터베이스의 해당 테이블에 저장하고로 이동합니다. 다음 사이트. 데이터베이스는 mysql 5.1, InnoDb 테이블 4 개, 뷰 4 개가있다. 테이블에는 테이블 조인에 사용되는 필드에 대한 숫자 인덱스가 있습니다. 또한 CodeIgniter에 쓰여진 구문 분석 된 데이터를 검색하고 검색 할 수있는 웹 인터페이스가 있습니다 (델타 인덱스를 사용하여 스핑크스를 검색 할 수 있습니다).Java-mysql 고부하 응용 프로그램 충돌이 발생했습니다.

서버 구성 :

CPU: Type Xeon Quad Core X3440 2.53GHz 
RAM: 4 GB 
HDD: 1TB SATA 
OS: Ubuntu Server 10.04 

일부 MySQL의 설정 :

key_buffer = 256M 
max_allowed_packet = 16M 
thread_stack = 192K 
thread_cache_size = 128 
max_connections = 400 
table_cache = 64 
query_cache_limit = 2M 
query_cache_size = 128M 
다음 옵션을 제외한 기본 매개 변수와

자바 머신 실행 : 데이터베이스, 스크레이퍼 과정 (18 개)의 URL에서 비어

-Xms1024m -Xmx1536m -XX:-UseGCOverheadLimit -XX:NewSize=500m -XX:MaxNewSize=500m -XX:SurvivorRatio=6 -XX:PermSize=128M -XX:MaxPermSize=128m -XX:ErrorFile=/var/log/java/hs_err_pid_%p.log

초 그리고 충분히 안정되었다. 그러나 urls 테이블에 384929 개의 레코드 (처리 된 전체 URL의 25 %)가 포함되어 있고 8.2Gb가 소요되는 2 개의 약한 작업 후에는 Java 응용 프로그램이 매우 느리게 시작되고 1 ~ 2 분마다 중단됩니다. 그 이유는 mysql은 증가하는 로딩을 처리 할 수 ​​없다는 것입니다 (파서는 2+4*BLOCK_NUMBER 처리 된 모든 쿼리를 쿼리하고, 매 10 분마다 델타 인덱스를 업데이트하는 스핑크스이지만 한 사람 만 사용하기 때문에 웹 인터페이스를 고려하지 않습니다.)), 아마도 인덱스를 매우 천천히 다시 작성합니까? 그러나 mysql 및 scraper 로그 (발견되지 않은 모든 예외도 포함)는 비어 있습니다. 당신이 그것에 대해 어떻게 생각하십니까?

+1

충돌에 대해 자세히 설명해 주시겠습니까? JVM 크래시입니까, 아니면 OutOfMemoryError와 같은 오류가 발생하고 있습니까? 응용 프로그램의 메모리 프로파일 링을 시도 했습니까? 아니면 최대 메모리를 늘리셨습니까? –

+0

OutOfMemoryError 예외는 아니며 몇 분 안에 자동 종료됩니다 (어쩌면 mysql로 ​​인해). 현재 웹 인터페이스가 응답하지 않으면 SQL 쿼리는 매우 느리게 수행됩니다 (300 초 이상). 나는 최대 메모리를 증가하려고하지만, 도움이되지 않습니다 – c1tru55

답변

0

나는 몇 상태 일을 확인하기 위해 바로 다음 실행 권하고 싶습니다 ..뿐만 아니라 도움이 여기에 출력을 퍼 팅 :

  1. dmesg
  2. top이 과정
  3. 당 가상 메모리 대 거주 확인
+0

** 정상 ** 'VIRT RES SHR %의 CPU % MEM COMMAND' '823m 53m 2,960 460 1.3 mysqld' '3,094m 1.9 1,000 329 49.1 java' – c1tru55

+0

와우 참 , 자바는 확실히 거기에 있습니다. dmesg에서 결정적인 것을 찾았습니까? - 어떤 쓰레드가 죽었는지 보여 주어야합니다. 또한 - 그 프로그램 중 하나의 메모리 사용 추세가 아직 눈치 챘습니까? 이'top -p [pid], [pid]'처럼 맨 위를 실행하면이 두 가지를 독점적으로 볼 수 있습니다. Java 응용 프로그램이 1 - 2 분마다 충돌하고 램 사용량이 1 - 2 분 이내에 실행되는 동안 언젠가 1.9g가되면 메모리 누수를 나타낼 수 있습니다. – technocrat

0

그러면 응용 프로그램이 응답하지 않게됩니까? (전혀 크래시와 같지 않습니다.) 모든 리소스가 무료인지 확인합니다. 예 : 어떤 스레드가 묶여 있는지 확인하려면 jstack을 수행하십시오.

MySQL을 체크인하면 연결 수가 예상됩니다. Java로 연결을 계속 작성하고 정리하지 않으면 데이터베이스가 더 느리게 실행됩니다.

0

모두에게 감사드립니다. mysql은 실제로 문제의 원인이었습니다. my.conf에서 느린 쿼리 로그를 활성화하면 모든 반복을 실행하는 쿼리 중 하나가 300 초 (검색을위한 1 개의 필드가 인덱싱되지 않음)를 수행한다는 것을 알 수 있습니다.

관련 문제