■ ZUM App (2021.11 ~ 2021.12) - ZUM 포털
1. AWS DynamoDB 설계
- 통합 푸시&개인화 RDBMS → AWS DynamoDB 모델링
- 기술블로그 작성 : https://zuminternet.github.io/DynamoDB
■ GETSTOCK (2022.01 ~ ing) - 비상장 주식 거래 서비스
1. 투표 시스템 구성
- 일반투표 / 예약투표 / 기간투표 / 선착순 투표
- 일반 투표와 앞으로 추가/삭제될 투표를 고려하여 확장적인 아키텍처 구성
- 기술블로그 작성 : https://zuminternet.github.io/vote-architecture
2. 선착순 투표 시스템 동시성 문제 해결
- 문제 : 선착순 마감 투표수보다 1개씩 더 투표되는 문제 발생
- 원인 : @Transational과 Mysql NamedLock 사이에서의 실행 순서 이슈
- 해결 : NamedLock을 수동 커밋으로 변경 후 동시성 제어
3. 리팩토링 : 정렬 파라미터를 전략패턴으로 변경
- 문제 : 뉴스 파라미터로 정렬(최신순, 오래된순 등등)이 늘어날 때마다 if문이나 switch문이 추가되는 형태
- 해결 : Spring Converter를 이용해서 파라미터로 들어오는 문자열을 Strategy패턴으로 받아서 해당 전략의 스프링 빈을 반환하는 형식으로 변경
4. 리팩토링 : 파라미터에 따른 각각의 뉴스 서버 호출
- 문제 : 특정 Service Layer에서 Switch문으로 각 뉴스 파라미터별로 각각의 뉴스 서버 호출
- 해결 : 각 뉴스를 객체로 승격 후 Strategy 패턴 사용, 요청으로 들어오는 파라미터를 Factory 패턴으로 구현체를 반환하여 각각의 뉴스 서버 호출
5. 크롤링 데이터 포맷 변환 커스텀 어노테이션
- 문제 : 배정 주식 수와 퍼센테이지 데이터 크롤링 작업
- 해결 : AOP + 커스텀 어노테이션을 활용하여, html 태그 제거 후 각 데이터들을 숫자 포맷으로 변경
5. 마스킹 커스텀 어노테이션
- 문제 : 사용자 이름, 전화번호, 이메일 등 간편하게 공통적으로 마스킹하는 작업 필요
- 해결 : @Masking 어노테이션을 생성하고 Masking Custom Serializer 구현, 각 마스킹 대상을 객체로 승격 후 Strategy 패턴 사용하고 각 마스킹 타입 별 구현체를 Factory 패턴으로 생성
6. 운영 수기 데이터 자동화
- 문제 : 운영팀에서 매일 한 번씩 IPO 데이터를 확인해서 수기로 데이터 적재 중
- 해결 : 운영 불편함을 줄이기 위해, IPO 데이터 자동화 제안 후 크롤링해서 매일 특정 시간마다 적재
7. prod와 stg 데이터 동기화
- 문제 : prod 데이터와 stg 데이터가 일치하지 않아서 테스트에 대해 불편함을 느낌
- 해결 : prod와 stg 데이터 동기화를 제안하고 매일 특정 시간마다 prod 데이터 덤프 후 stg에 적재
8. 로컬캐시 → 글로벌 캐시
- 문제 : 모든 캐시가 로컬 캐시(Ehcache)를 사용중
- 해결 : 거래 게시글 등 데이터 정합성을 위해 글로벌 캐시(Redis)로 이전 제안 후 이전 작업
9. 장애 알림
- 문제 : 거래 시스템을 운영하기 때문에 API 장애 시 크리티컬하다고 판단, 장애 발생 시 개발망에서 로그를 직접 찾아보면서 장애 시간 지연
- 해결 : 빠른 장애 대응을 위해 장애 알림 슬랙 봇 도입
- 결과 : 저희 팀은 장애 리커버리가 빨라졌으며, 리커버리하는 시간을 줄일 수 있어서 팀원들이 좋아하는 모습을 보고 저도 덩달아 기뻤던 경험
■ InvestingView (2023.02 ~ ing) - 주식 정보 제공 서비스
1. 슬랙 장애 알림 커스텀 어노테이션
- 문제 : 인수인계 받은 프로젝트에서 각 모듈 별로 예외처리를 진행하고 있는 상황
- 해결 : 공통 모듈에 @NotifySlack 이라는 커스텀 어노테이션을 생성하고 각 모듈의 장애 알림을 공통 모듈에서 처리
2. Latency 개선
- JavaMelody를 활용해서 각종 API Latency 모니터링
- 100ms이상 걸리는 API 확인 후 Latency 개선
3. 주식 등락 타입 쿼리스트링을 전략 패턴으로 받아서 분기 처리 제거
- 문제 : 주식 등락 타입(상승, 하락, 보합)의 쿼리스트링으로 받으면 비즈니스 로직 어딘가에서는 분기 처리 불가피
- 해결 : Spring Converter를 이용해서 쿼리스트링으로 들어오는 문자열을 Strategy패턴으로 받아서 해당 전략의 스프링 빈을 반환하는 형식으로 변경 (분기 처리 제거)
■ 커뮤니케이션
1. 거래 주문 번호 PessimisticLock 리뷰
- 문제 : 동료분께서 거래 주문 번호 생성 시 여러 요청이 들어올 경우 중복으로 생성하지 않는 방법 고민
- 제안 : 팀에 합류하고 추후 동시성 문제가 생길 것을 대비해서 jOOQ OptimisticLock과 PessimisticLock 을 학습해서 포스팅한 것이 있었는데 해당 포스팅을 공유하고 리뷰
- 결과 : 동료분께서 해당 포스팅을 참고하고 GitHub의 테스트코드를 참고해서 거래 주문 생성시 PessimisticLock을 사용해서 적용
2. Redis SortedSet 자료구조 리뷰
- 예상 : 추후 선착순 비상장 주식 이벤트를 할 것을 예상, 대비
- 제안 : Redis SortedSet 자료구조를 학습하고 블로그 포스팅 후에 팀원들에게 리뷰
- 결과 : 선착순 이벤트을 진행하진 못했지만, 팀원분께서 종목별 기업가치 랭킹을 구성할 때 Redis SortedSet 제안 후 리뷰 및 적용 서포트
3. Circuit Breaker 리뷰
- 문제 : 외부(증권사, 각 모듈) API 호출이 많기 때문에 특정 서버에 장애가 날 경우, 특정 서버를 호출하는 클라이언트 서버까지 장애가 전파될 것을 우려
- 제안 : Circuit Breaker 학습 후 블로그 포스팅하여 팀원들에게 리뷰
- 결과 : CTO님께 컨펌 받았으며 도입 예정이었으나 타 증권사와의 서비스가 잠정적 중단되어 도입 미정
4. Redis Write Back 전략 제안
- 문제 : 타 팀에서 코스콤에서 실시간으로 받아오는 주식 데이터를 레디스와 DB에 Double Write를 하는 도중에 컨슈머 랙이 계속 쌓이는 현상 발생
- 제안 : Redis에 먼저 적재하고 주기적(30초, 1분 등)으로 DB에 적재하는 Write Back 전략 제안
- 결과 : Write Back 적용 후 컨슈머 랙 줄어듦
5. 리팩토링 제안
- 문제 : 인수인계 받은 프로젝트의 Controller단에 HATEOAS의 Link를 중복적으로 생성하는 코드 발견
- 제안 : 저보다 연차가 낮으신 팀원 한 분께 해당 사항 공유하고 AOP와 커스텀 어노테이션으로 리팩토링 제안
- 결과 : Controller단은 깔끔해지고, 커스텀 어노테이션과 AOP를 잘 모르고 있었는데 학습과 이력에 도움이 될 것 같다고 너무 감사하다고 피드백 받음
6. 팀 내 개발 문화
- 코드 리뷰 제안, 팀원들과 논의 후 및 도입
- 팀 내에 스터디를 만들어서 사내 스터디 진행
- 영감 깊게 본 아티클, 책, 영상(강의, 유튜브)에서 아이디어를 얻고 이를 토대로 테스트 코드와 블로그 포스팅을 통해 팀원들 & 사내 Slack 채널에 공유
- 최근에 신입분이 한분 팀에 합류하셨는데, OOP와 SOLID를 꾸준히 설명해드리고 있으며, 제가 학습했던 책과 강의를 토대로 추천해드리면서 가이드
7. 타 팀(기획/전략팀 등)과의 커뮤니케이션
- 개발을 진행하면서 기획서에 없는 내용이더라도 사내 내부 운영 측면이나 서비스에 추가됐으면 하는 부분들 조심스럽게 제시
더보기