프록시 서버(cpu : 4코어, 메모리 : 8GB)로 받은 API 데이터를 WAS로 전송하지 못했을때 데이터를 파일로 만들어서 주기적으로 재전송 하는 스케줄러 개발
요구사항.
재시도 횟수 5회까지는 1분 마다 Call
재시도 횟수 5회 이상 10회 까지는 30분마다 Call
재시도 횟수 10회 이상일때는 Fail 폴더로 이동
파일명에 _숫자로 재시도 횟수를 표현 했고 1분, 30분 간격으로 돌아가는 스케줄러 두개를 만들었다.
Files.walk로 스트림으로 파일들을 가져와서 WAS를 호출하고 실패하면 파일명에 재시도 횟수를 증가하게 했다.
몇만건 데이터를 처리하는데 문제가 없었으나 백만건 이상 파일을 만들어서 테스트를 하니 OOM이 발생했다.
1. 속도 저하
스래드 5개로 파일을 돌렸는데 TPS가 150 정도만 나왔다. Files.walk를 사용할때 스래드풀을 forEach에서 사용하였지만 스트림이 단일스레드라서 느렸다. parallel 추가로 해결(cpu 코어 -1 만큼 병렬로 동작) -> 리소스 너무 많이 사용하면 common pool 생성 후 사용 예정
파일을 불러올대 최대 크기가 15KB 정도라서 버퍼 추가로 한번에 16KB씩 읽게 변경
ObjectInputStream(new BufferedInputStream(new FileInpuStream(file.toFile()), 16*1024)))
2. 대용량 파일 처리 시 OOM 발생
원인은 파일이 많아서 스케줄러가 돌고 있을때 다음 스케줄러가 멈춰야 하는데 계속 돌아서 OOM이 발생
다음 스케줄러를 멈추기 위해 Files.walk로 파일목록(path)을 ConCurreentLinkedQueue에 저장(100만건 100MB), CountDownLatch로 파일이 모두 처리 될 때까지 스케줄러 중지
혹시 모를 오류 발생 시 스케줄러 종료를 위해 Future 사용해서 개별 스레드 정지 추가
latch.await(timeout)로 특정시간 넘어가거나 countDownLatch=0 이 될때까지 스케줄러 동작
결과
TPS : 500, 메모리 : 100만건 100MB으로 cpu, 메모리 안정성 확인.
최대 파일 개수가 50만건 정도로 예상했기에 100만건 테스트 수행결과 이상없음으로 배포 완료
'개발 > Java' 카테고리의 다른 글
레거시 스케줄러에 배치 처리 방식 적용하기 (1) | 2025.03.24 |
---|---|
자바 기초1 (0) | 2021.03.30 |