개요
프로젝트 진행 중 오픈 API의 데이터를 읽어 통합 데이터로 수집하는 배치 프로그램을 개발하는 업무를 담당하게 되어 업무 진행 간 겪은 경험들을 기록하고자 함.
분석
1. 각각의 오픈 API에 있는 모든 데이터를 수집해야 한다.
2. API의 데이터는 대부분 페이지 방식으로 적용되어 있다.
- pageNo = 1, RowNum = 10
3. 오픈 API의 URL 마다 다음 데이터를 나타내는 URL이 각각 다르다.
- page & row 방식, first row & last row 방식
4. 오픈 API 중 인증키를 요구하는 API도 있다.
5. 오픈 API에서 요구하는 필수 Paramter가 존재한다.
6. 연계된 오픈 API에서 가져온 데이터를 기반으로 수집해야 하는 API도 존재한다.
7. 수집한 데이터의 포맷이 XML 과 JSON 두 가지의 포맷이 존재한다.
8. 모든 API는 실행주기를 갖고 있고 실행주기가 도래하면 실행되어야 함.
설계
기본적인 배치 프레임워크는 스프링 배치를 이용하기로 하였다.
스케줄러는 Jenkins를 이용하기로 함.
xml, json parser는 비교적 메모리를 사용하는 공간을 적게 차지하는 SAX Parser를 적용하기로 하였다.
SAX Parser는 라인단위로 분석하기 때문에 xml 데이터를 모두 메모리에 올려놓지 않아도 되기 때문에 속도 향상에 이점이 있을거라 판단했다.
최초 설계는
1. 실행주기가 도래한 API 목록 수집
2. API의 url 생성을 위한 객체 생성
3. url을 통해 데이터 수집 - parse - DB적재
4. 연계 API 데이터 기반 수집이 필요한 API 별도로 진행
이렇게 큰 틀을 잡고 항목마다 Tasklet으로 구현하기로 계획했다.
스프링 배치에서 권장하는 Chunk 방식으로 구현하려고 하였으나 당시에는 아직 스프링 배치에 대한 지식이 부족해 Tasklet으로 구현하기로 함.
하지만 중간 중간 요구사항이 너무 많이 추가되고 변경되었기 때문에 최초 설계부터 유연하게 설계하였음에도 몇 번의 리팩토링을 진행했다...
1. Paramter가 고정값이 아닌 사용자가 설정한 값도 포함되어야 한다.
- "제목 : " + titleName -> 제목 : 태그값
해당 요구사항을 반영하기 위해 parameter를 단순한 자료구조로 적용했었던 것을 별도의 자료구조 객체로 구현
2. PKIX 이슈 발생
- 자바 jdk에 사설 인증키를 추가하는 기능 추가
3. 싱글 스레드로 동작 시 데이터 수집 시간이 너무 오래 걸림.
- 스프링 배치 멀티스레드 적용
url 생성을 담당하는 URLBuilder를 구현하여 url 생성 목적에만 집중
URLBuilder를 제작하고 page & row 방식, first row & last row 방식으로 크게 분류하여 다음 데이터를 수집할 수 있도록 적용
URLBuilder로 부터 생성한 URL을 이용하여 Map 구조의 데이터를 수집하는 Collector 객체 생성
Map 구조의 데이터에서 원하는 형식대로 데이터를 가공하여 적용하는 Processor 객체 생성
최종적으로 이렇게 설계 구조를 잡게 되었다.
개발
개발을 진행하며 리팩토링을 2번정도 했다.
개발이 거의 완료되었을 즈음 전체 API를 대상으로 테스트를 진행했다. 당시에는 싱글스레드 기반으로 설계를 했고 막상 실행을 해보니 속도가 너무 느린 것이다. 그래서 스프링배치에 멀티스레드를 적용하기로 하고 전체 리팩토링을 진행했다.
URL을 생성하는 Builder쪽은 멀티스레드에 영향을 거의 받지 않았지만 URL생성 후 수집을 진행하는 스프링 배치 쪽에서 멀티스레드의 영향으로 중복 수집이 계속 발생하였기 때문이다.
멀티스레드를 성공적으로 적용하고 데이터 수집도 정상적으로 되는 것을 확인하고 최종테스트까지 완료한 후 운영서버에서 실행을 했을 때 데이터나 배치프로그램 자체에는 문제가 없었으나 너무 과도한 DB작업으로 인해 생각보다 DB 부하가 많이 발생하는 것으로 나타났다.(DB 서버의 하드웨어 성능이 그닥 좋지 못하다)
이러한 이유로 WAS 서버에서 적용하던 것과 동일하게 Mybatis를 적용하라고 해서 작업을 했으나 JPA로 변경하게 되었다.
Mybatis도 물론 객체 중심 설계가 가능하지만 필자의 경우는 아무래도 Mybatis를 사용하던 습관인 탓인지 자바프로그램에서 진행할 수 있는 업무를 자꾸 데이터베이스로 넘기게 된다.
JPA로 변경할 때는 Enitiy 작업 때문에 시간이 많이 소요되었으나 한 번 작업해 놓으니 어떤 테이블에 작업을 하던 수월하게 진행이 되었다. DB부하도 많이 줄어들었다.
저장소 링크
'project' 카테고리의 다른 글
[C++] 에이스타(A*) 알고리즘을 구현한 최단 경로 이동 시뮬레이션 개발 (0) | 2023.07.12 |
---|---|
[Go] Golang을 이용한 칼만 필터 적용 구현 및 시뮬레이션 (0) | 2023.07.11 |
[Project] SECS 프로토콜을 이용한 데이터 통신 Conversion Server 개발기 (0) | 2023.04.24 |
[Project] Develop Database Middleware server project (0) | 2022.07.14 |