← 프로젝트 목록으로

SOC Portal

교보 DTS · 부트캠프 기업협업 프로젝트 · 2024.04 – 2024.06

Frontend · FE 1 / BE 3

SIEM에서 탐지된 1만+ 건의 로그 티켓을 관리하는 백오피스

ReactJavaScriptStyled-componentsAxios

구현 기능

  • 티켓 목록 응답 시간 17.53s → 46ms 최적화 (dataState 상태 머신)
  • 실시간 관제 대시보드 및 기간별 차트 렌더링 최적화
  • 1만+ 건 SIEM 탐지 로그 티켓 목록 조회 · 필터링 · 페이지네이션
  • 이슈 이력 조회 페이지
  • 이메일 알림 등록 · 수정

트러블슈팅

1. 티켓 목록 응답 지연: dataState 트리거 상태 머신

문제
  • 800만 건 규모 데이터 환경에서 조건에 맞는 49만 건을 세는 COUNT와 목록 조회가 한 응답에 함께 처리되어 17.53초가 걸렸습니다.
원인
  • 목록·페이지 정보·총 개수를 한 응답에 묶어서 반환하는 구조 때문에 느린 COUNT 쿼리를 목록 조회까지 계속 함께 기다리고 있었습니다.
  • 검색 조건이 그대로인 상태에서 페이지만 넘겨도 COUNT 쿼리가 매번 재실행되어 느려지고 있었습니다.
해결
  • 백엔드와 협의해 목록·페이지 정보·총 개수를 한 번에 반환하던 API를 목록 조회 API와 COUNT API로 분리했습니다.
  • 이 두 API를 언제, 어떤 순서로 호출할지 제어하는 dataState 상태 머신을 설계하여 목록 응답이 오면 먼저 화면을 그리고 dataState가 true로 바뀐 뒤에만 COUNT를 요청하도록 했습니다.
  • 페이지 이동 시에는 COUNT를 재요청하지 않고, 검색 조건이 바뀔 때만 다시 동작하도록 했습니다.
개선 전 · 17.53s
개선 후 · 46ms
src/components/pages/ticket/Ticket.jsx
setDataState(true); // 카운트 비동기 처리를 위한 state 변경

// 필터 변경 시 카운트 재요청 전, 낡은 상태부터 리셋
if (searchFilter && filterOptions != null) {
  setCurrentPage(0);
  setDataState(false);
}

// dataState가 true로 바뀐 뒤에만 count 요청
useEffect(() => {
  if (searchFilter && filterOptions != null && dataState === true) {
    setTotalPages(10);
    fetchTicketCount();
  }
}, [filterOptions, dataState, pageSize]);

결과: 목록 응답 17.53s → 46ms. COUNT는 페이지네이션과 분리되어 2.30s로 단축되고, 목록과 비동기로 처리되어 체감 대기 시간이 사라짐

2. 5분 인터벌 차트가 매번 재요청되는 문제: 키 기반 Promise 캐시

문제
  • 실시간 대시보드 차트가 5분마다 구간을 갱신할 때마다 동일한 데이터를 다시 요청해 화면이 깜빡였습니다.
원인
  • 차트 컴포넌트가 인터벌마다 새로운 Promise를 생성해 캐시 없이 fetch를 반복했습니다.
해결
  • company-period-startDate 키 기반 Map 캐시에 fetch Promise를 저장했습니다.
  • 동일한 구간이면 캐시된 Promise를 재사용하도록 React의 use() 패턴을 직접 구현했습니다.
src/components/pages/dashBoard/AreaGraph.jsx
const key = `${selectedCompany}-${selectedPeriod}-${startDate}`;

if (cache.has(key)) return cache.get(key);

const promise = fetchDashBoardGraph(selectedCompany, selectedPeriod.timestamp);
cache.set(key, promise);

결과: 동일 구간 재조회 시 중복 요청·재-suspend·깜빡임 제거