글 목록

엑셀 대량 등록 시 서버 검증과 클라이언트 피드백의 분리 설계

대용량 엑셀 업로드 시 서버의 전체 검증 결과와 클라이언트의 실시간 피드백을 분리해, 사용자에게 즉시 시각화된 대조표를 제공한다. 서버 부하를 줄이면서도 사용성을 확보한 아키텍처 결정 과정.

주재범5분 읽기

배경

대량 데이터 등록은 항상 두 가지 상충되는 요구사항을 안고 다닌다. 서버는 무거운 검증 로직을 처리하며 안정성을 유지해야 하고, 사용자는 수천 줄의 데이터 중 어느 줄이 틀렸는지 즉각적으로 확인하고 싶어 한다. 전통적인 패턴은 엑셀 파일을 서버에 올리고, 서버가 전체 파일을 파싱·검증한 후 실패한 줄의 인덱스 목록이나 에러 메시지를 반환하는 방식이었다.

이 방식은 구현이 단순하지만 치명적인 결함이 있다. 서버가 전체 파일을 다 검증해야 하므로 응답 시간이 길어지고, 타임아웃이 발생할 확률이 높아진다. 사용자는 긴 대기 시간 끝에 "에러 발생"이라는 메시지만 받고, 어떤 줄이 문제인지 알 수 없어 다시 파일을 수정해야 한다. 이 과정에서 사용자는 반복적인 업로드-실패-수정 사이클에 갇히게 된다.

물류 플랫폼의 계약서 등록 기능에서도 같은 문제가 발생했다. 계약서 등록은 거래처 정보, 품목, 운임 조건 등 복잡한 비즈니스 규칙을 따르므로 검증 로직이 무겁다. 기존에 계약서를 하나씩 등록하는 화면은 사용자에게 즉각적인 피드백을 줄 수 있었지만, 엑셀로 대량 등록할 때는 그 장점을 살리지 못했다.

문제를 느낀 계기

사용자들이 엑셀 일괄 등록 기능을 쓸 때 가장 많이 불만족해하는 지점은 '검증 결과의 불투명성'이었다. 서버가 반환하는 에러 메시지는 기술적인 내용(예: "거래처 ID 존재하지 않음")이어서, 사용자는 자신의 엑셀 파일에서 어느 행의 어떤 셀이 문제인지 매칭하기 힘들었다.

또한, 서버 부하도 문제였다. 수천 줄의 엑셀 파일을 올릴 때마다 서버는 모든 줄을 검증해야 했으므로, 메모리 사용량이 급증하고 GC 부하가 커졌다. 이는 다른 기능의 응답성에도 영향을 미쳤다.

우리는 이 문제를 해결하기 위해 서버와 클라이언트의 역할을 재정의했다. 서버는 '검증'에 집중하고, 클라이언트는 '피드백'에 집중하는 구조다.

제약

이 설계를 구현할 때 고려한 제약은 세 가지였다.

첫째, 검증 로직의 중복을 피해야 했다. 서버가 반환하는 검증 결과는 클라이언트에서 다시 검증하지 않아야 한다. 클라이언트는 서버의 결과를 신뢰하고 표시만 해야 한다.

둘째, 대조표의 매칭 로직은 복잡해지지 않아야 한다. 엑셀 파일의 행과 서버의 검증 결과를 매칭할 때, 인덱스 기반 매칭은 파일 수정 시 흔들리기 쉽다. 고유 키 기반 매칭이 필요하지만, 엑셀에는 고유 키가 없을 수 있다.

셋째, 서버의 응답 크기는 제한되어야 한다. 수천 줄의 에러 메시지를 모두 반환하면 네트워크 부하가 커진다. 따라서 '바로 등록'과 '확인 필요'로 결과를 분류하고, 클라이언트가 필요한 정보만 요청하도록 설계해야 했다.

선택지

전통적인 전체 검증 반환

  • 장점: 구현이 단순하다. 서버가 모든 에러를 반환하므로 클라이언트는 복잡한 로직이 필요 없다.
  • 단점: 응답 시간이 길고, 타임아웃 위험이 높다. 사용자가 에러를 이해하기 어렵다.

클라이언트 측 검증

  • 장점: 서버 부하가 줄어든다. 실시간 피드백이 가능하다.
  • 단점: 클라이언트와 서버의 검증 로직이 동기화되기 어렵다. 비즈니스 규칙 변경 시 양쪽을 모두 수정해야 한다.

대조 테이블 공유

  • 장점: 서버는 검증 결과만 반환하고, 클라이언트는 이를 시각화한다. 사용자는 대조표를 통해 에러를 직관적으로 이해할 수 있다. 서버 부하도 줄어든다.
  • 단점: 클라이언트에서 대조표 매칭 로직을 구현해야 한다. 초기 개발 비용이 높다.

결정

우리는 대조 테이블 공유 방식을 선택했다. 서버는 엑셀 파일을 받으면 검증하고, 결과를 '바로 등록'과 '확인 필요' 두 개의 표로 반환한다. 클라이언트는 이 두 표를 받아 사용자에게 시각화한다.

구체적인 흐름은 다음과 같다.

  1. 사용자가 엑셀 파일을 업로드하면, 서버는 파일을 파싱하고 검증한다.
  2. 검증 결과는 두 개의 표로 반환된다. '바로 등록' 표는 검증에 성공한 줄들의 고유 키와 함께 반환된다. '확인 필요' 표는 검증에 실패한 줄들의 고유 키와 에러 메시지가 함께 반환된다.
  3. 클라이언트는 '바로 등록' 표와 '확인 필요' 표를 받아, 엑셀 파일의 행과 매칭한다.
  4. 매칭된 결과는 사용자에게 대조표 형태로 시각화된다. '바로 등록' 행은 녹색, '확인 필요' 행은 빨간색으로 표시된다.

고유 키 기반 매칭을 위해, 엑셀 파일에는 고유 키를 포함하도록 양식을 제공한다. 만약 고유 키가 없다면, 서버와 클라이언트 모두 행의 인덱스를 기반으로 매칭한다. 이 경우 파일 수정 시 흔들릴 수 있으므로, 사용자에게 파일 수정 후 다시 업로드하도록 안내한다.

결과와 한계

이 설계로 인해 사용자는 엑셀 업로드 후 즉시 어떤 줄이 문제인지 확인할 수 있게 되었다. 또한, 서버의 부하도 줄어든 효과도 있었다. 서버는 검증 결과만 반환하므로, 응답 크기가 줄어들었고, GC 부하도 감소했다.

하지만 한계도 있다. 클라이언트에서 대조표 매칭 로직을 구현해야 하므로, 초기 개발 비용이 높았다. 또한, 엑셀 파일의 형식이 변경될 때마다 클라이언트와 서버 모두 수정해야 한다는 점도 고려해야 한다.

다른 시스템에 적용할 때, 대용량 데이터 등록 시 서버와 클라이언트의 역할을 분리하는 것이 유용할 수 있다. 특히, 검증 로직이 복잡하고 사용자의 실시간 피드백이 중요한 경우에 이 방식을 고려해볼 만하다.

팀에 남긴 규칙은 대량 데이터 처리 시 서버는 검증에만 집중하고, 클라이언트는 피드백에 집중하는 아키텍처를 기본으로 삼는다.

이 글 공유
LinkedInThreadsX