1. 락커 TCP 커넥션이 끊긴 후, 다시 붙지 않아 제어가 안되던 장애

    1. 락커 TCP 커넥션이 주기적으로 끊기고, 다시 재연결되지 못하는 문제가 있었습니다. 비동기 TCP통신이라 원인파악 어려웠지만 최대한 추적 및 분석하였고, 블록이 걸리는 원인을 수정하여 해결 => 이후 동일한 원인으로 인한 문제가 다시 발생하지 않았습니다.
    2. 개선 내용 링크
      1. Netty 이벤트 루프 쓰레드에서 블로킹을 쓰면 발생하는 문제
  2. 실제 현장 방문을 통한 여러가지 장애 해결 및 성능 개선

    1. 스피드게이트 및 출입통제기 출입시에 딜레이가 1~1.5초 나던 성능 문제가 있었습니다. 성능 이슈를 만드는 포인트를 찾아 코드 개선 및 인덱스를 설정하였고, 0.1~0.2초 안에 출입이 가능하도록 개선되었습니다.
    2. 키오스크에서 이용권 사용 시에 사용처리되기까지 2~3초 딜레이가 발생하던 성능 문제가 있었습니다. 역시 성능 이슈를 만드는 포인트를 찾아 작업했습니다. 기본적으로 이용권이라는 기능 자체가 클라우드 서버에 구현이 되어있는 데다가 상당히 많은 통신을 요구로 하여 성능이 안나오던 문제인데, 병렬적으로 혹은 비동기 처리되어도 무리가 없는 부분을 변경하여 0.3초 이내로 개선 되었습니다.
    3. 기기 자체 결함으로 인한 통신 장애를 여러 건 해결하였습니다. 업체 측 문제로 데이터 통신이 이루어지지 않던 문제임에도, 이에 대한 인정을 하지 않아 직접 현장에서 대면하는 방향으로 소통하였습니다. 결국 대면 자리마다 항상 업체 하드웨어나 통신 문제인 것을 증명하여 업체 측의 유지보수 및 교체 작업을 유도해냈습니다.
  3. 분산락을 잡아 동시성으로 인한 문제 해결

    1. 이용권 매달 정산 시에, 운영툴에서 중복 클릭 등으로 인해 정산이 종종 두번 이루어져서 서버에 과부하를 주거나 데이터 불일치를 일으키던 문제를, redis 서버를 통한 분산락을 잡아서 해결하였습니다.
  4. 장기간 이력에 대한 엑셀 생성 작업에 대한 시간 소요 해결

    1. 이력 엑셀 생성 시에, 매우 큰 기간을 설정하였을 때 클라이언트 UX 상 오랜시간 동안 기다려야하는 문제가 있었습니다. 우선 비효율적인 쿼리를 개선하였습니다. 1000개씩 조회를 한다고 가정했을 때, 일반적인 페이지네이션 처리를 하면 불필요한 TotalCnt 쿼리가 지속적으로 발생합니다. 이를 Slice 방식으로 변경하여 쿼리 성능을 개선하였습니다. 그리고 Query Plan을 통해 인덱스를 분석하고 정리하여 효과적인 인덱스 스캔이 이루어지도록 수정했습니다. 추가로 엑셀 생성 작업을 비동기 백그라운드 처리하여 UX를 더욱 개선하였습니다. 길면 생성까지 10분 이상 걸리던 성능이 20~30초 이내로 단축되었습니다.
  5. 이벤트 발행 → API 방식 변경

    1. 불필요하게 많은 통신을 이벤트로 처리하고 있던 부분에 있어서 API 방식으로 변경하여 동기화 문제를 최소화하는데 기여함
  6. 이벤트는 되도록 새로운 메세지큐 사용하도록 변경

    1. 다양한 성능 이슈와 메시지 유실 문제를 일으킨 ActiveMQ를 걷어내고, 전체적으로 CDC 카프카를 사용하는 방향으로 변경이 요구되어, 담당하는 도메인의 몇몇 이벤트를 카프카로 변경
  7. 이력/정산 서버 정리 및 DB 인덱스 정리, 컨벤션에 맞게 리팩토링

    1. 이력서버와 정산서버에서 오래도록 사용되지 않는 기능에 대해 제거 및 정리하였습니다. 이력서버 통합을 위한 사전과정으로 진행하였습니다.
    2. 컨벤션에 맞지 않게 네이밍 된 클래스나 패키지 구조를 전면 개편하고, 변수명 메서드명 등도 전부 회사 컨벤션에 맞게 수정하여 최대한 잘 읽히고 이해될 수 있도록 유도하였습니다.
    3. 조회 이력 인덱스 중에 실제로 타지 않는 인덱스나, 비효율적인 인덱스를 제거하고, 일관성, 사용성, 우선순위에 맞게 조정하였습니다. 이를 위해 클라이언트에서 사용하던 UI/UX를 수정하기도 했습니다.
  8. 이력 서버 통합을 통한, 이력 데이터 사이에 싱크 문제 해결

    1. 최초에 에이치티비욘드의 이력서버는 생성 및 수정을 전담하는 원장 이력 서버와 조회를 전담하는 조회 이력 서버로 나누어져 있었습니다.
    2. 원장 이력 생성 이후에, 이력 생성 이벤트를 발행하면 이를 정산서버가 수신하여 금액이 있는 이력인 경우에 정산 이력을 만들고, 없으면 만들지 않고 또 정산 데이터 생성 이벤트를 발행합니다. 조회 이력 서버에서는 이를 수신하고, 회원 서버를 통해 회원 정보를 추가로 조회해와 조회이력을 생성하게 됩니다.
    3. 이는 최대한 플로우를 간단하게 설명한 부분인데, 훨씬 다양한 이력 생성 요구사항에 대하여 복잡한 플로우로 구현되어 있습니다. 가령 이벤트가 유실된다면? 가령 API 통신에 실패한다면? 주기적인 데이터 동기화 문제가 발생할 수밖에 없습니다. (하루에도 수십건 씩 발생하여 꾸준히 동기화 체크 스크립트를 돌리고 데이터를 보정해왔습니다.)
    4. 굳이 이력을 나누고 정산 서버를 중간에 둠으로써 이런 문제를 야기할 필요가 없다고 판단했습니다. 이를 해결 하기 위해 이력 서버를 통합하고 정산서버와의 의존성을 최소화 하는 작업을 진행했습니다. 서버와 데이터베이스를 합치고, 이벤트를 정리했습니다. 이후 전혀 데이터 동기화를 신경쓰지 않아도 되는 수준으로 개선되었습니다.