KakaoVX
골프예약 시스템, 골프장 ERP 연동 시스템, 관리자툴 유지보수 부분을 담당하여 진행하였습니다.
골프예약 운영 <트러블슈팅>
ERP 배치 서비스가 랜덤한 시점에서 다운되어 APM 도구(Dynatrace)를 사용하여 문제를 분석하고 JVM 분석 도구를 통해 트러블슈팅을 진행한 경험입니다.
문제:
- 기본 생성자가 Integer.MAX_VALUE 크기 큐 할당 -> 메모리 과다 사용
- HttpResponse 미반납 → 메모리 점유 증가
해결:
- 서버 스케일업 (긴급대응) - 일시적 해결, 근본 원인 해결이 아님
- dynatrace를 통한 메모리 사용량 분석
- jmap을 통한 메모리 사용 객체 분석
- LinkedBlockingQueue 크기 100만 개 제한 -> 메모리 4GB 감소
- finally 블록에서 EntityUtils.consumeQuietly(response.getEntity()) 호출
- try-with-resources가 최선이지만, 기존 코드 의존성으로 최소한의 변경 적용
- 이후 팀 리팩토링 기간에 try-with-resources 구조로 변경
배운 점:
JVM 메모리 분석 활용 능력 향상
- 멀티스레딩 환경에서
큐 크기 관리 중요성 확인
- 운영 중 메모리 문제를 신속히
분석 & 해결하는 역량 확보
결과:
- 더 이상 메모리 사용량 증가로 인한
서버 다운 발생하지 않음
- 메모리 사용량 총
5GB 감소
골프예약 ERP 연동 시스템 <리팩토링>
300개 이상의 골프장의 각 요구사항을 수용해야하고 6개월~1년 안에 계약 변경으로 인한 ERP 변경시 마다 해당 요구사항을 지속적으로 반영해주어야 하는 문제가 있었습니다. 그로인한 기술 부채를 주도적으로 해결한 경험입니다.
문제:
- 4,500+ 라인 이상의 단일 클래스에 모든 비즈니스 로직 집중
- 하드코딩된 분기 처리로 인한 코드 가독성 저하
- 객체지향 설계 원칙 미준수에 따른 확장성 없는 코드들
해결:
- BookTime, BookTimeAdapter 등 핵심 로직의 도메인들을 객체로 분리
- 도메인별 책임과 역할을 명확화
- 비즈니스 로직의 응집도 향상
- 디자인 패턴 적용을 통한 구조 개선
- 전략 패턴:
- ERP별 날짜 변환 로직이 모두 달라 분기처리 하던 부분을 인터페이스를 작성하여 해당 구현 클래스를 주입하는 형태로 로직을 추상화
- 골프장별 특가 적용을 위한 하드코딩들을 하나의 클래스에서 분기처리 하던 부분을 인터페이스를 작성하여 구현 클래스를 주입하는 방법으로 분리
- 새로운 요구사항 발생 시 전략 클래스를 추가하여 적용할 수 있도록 확장성 확보
- 팩토리 패턴:
- 배치 실행시 여러개의 ERP 로직을 인터페이스로 추상화 하여 ERP 코드 작성시 필요한 메서드들을 미리 정의해둠
- 모든 ERP 구현 클래스는 ERP 인터페이스를 상속하여 사용하고 Picker 클래스를 통해 해당 골프장에 맞는 ERP 로직을 찾아 실행하도록 중앙화 시스템 처리
- 객체 생성 로직과 비즈니스 로직을 분리하여 코드의 복잡도를 줄임
- 어댑터 패턴:
- Adapter Interface로 외부 시스템 연동 추상화
- 외부 시스템 변경시 해당 골프장의 로직과 시스템의 로직이 분리되어 있어 시스템간 결합도 감소
- 골프장별로 상이하게 전달되는 반환 값들을 골프예약 시스템에서 필요한 데이터들로 변환할 수 있도록 처리
배운 점:
디자인 패턴을 적용하여 시스템 유연성을 확보할 수 있는 것을 배울 수 있었습니다.
레거시 시스템 리팩토링 경험을 얻을 수 있었습니다.
결과:
- class 별 평균 작성 코드 라인
평균 90% 감소 (4개의 class로 분리 400줄 이하)
- 코드
중복률 40% 감소
- 도메인 응집도 향상으로
기능별 구분이 쉬움
- 하나의 기능의 변경에 대한
영향도 최소화로 골프장별로 변경에도 큰 이슈 없이 적용 가능
- 새로운 ERP 업체 연동시
interface 구현만으로 확장 가능
- 골프장의 요구사항 or ERP 업체 변경시 비즈니스 로직이 직접 수정되는 것이 아닌
전략 class 수정만으로 변경 가능
무료 셔틀버스 <동시성, 문제해결>
버스 예약이라는 도메인을 처음 접하게 되었고 DB 설계부터 모두 담당하여 진행하게 되었습니다. 또한 외부 전산 시스템이 없는 버스 회사와 협업하여 예매 시스템 개발하여 적용해본 경험입니다.
문제:
- 예매 및 모집 API 개발
- 정류장 및 예약 데이터 모델링
- 동시성 문제 해결을 위한 Lock 적용
- 동시 예약 시 동일 좌석이 중복 예약되지 않도록 처리
해결:
- 기획팀과 회의를 통해 요구사항을 분석 →
- 문서 작성 (flow char, sequence diagram, db erd)
- Redis Lock 적용 → Lock Key를 설정하여 동시성 문제 해결
배운 점:
- 팀원들과 문서를 통해 협업에 사용하고 문서를 작성하며 도메인에 대한 이해도가 높아짐
- 서버 간 분산 환경에서는 단일락, DB락이 있지만
Redis 기반 분산 Lock이 효과적
결과:
- 처음으로 모든 시스템을
담당하여 진행 후 운영 동안 문제 발생률 0%
- 협업에서의
문서 중요성을 배움
- 서비스 중
동시 예약건수 0%
골프 예약 메인 캐싱 개선 <트래픽>
메인 페이지에서 반복적인 많은 데이터 반환으로 인해 트래픽이 집중되어 서버 리소스 최적화를 진행해본 경험입니다.
문제:
- 트래픽 증가 시 성능 저하 발생
- 이미지 사용으로 인한 서버 부하
- 관리툴에서 메인 수정 시, 변경 사항이 즉각 반영되지 않음
해결:
- Redis 캐싱 적용 → List API에서 JSON 데이터를 5분간 캐싱하여 서버 부하 감소 및 성능 최적화
- 관리툴에서 이미지 등록 시 Redis 캐싱 무효화 전략을 적용하여 즉각 적용되도록 처리
배운 점:
- 트래픽이 몰리는 서비스에서는 캐싱 전략이 필수적
- 데이터 변경 시
캐싱 무효화 전략을 통해 실시간 반영 가능
- 사용자 경험을 개선하는 것이 서비스 최적화의 핵심
결과:
- API 응답이
1초 이상 걸리던 문제를 0.1초 이하로 응답하도록 개선