별도 게이트웨이 없이 프론트·서버가 각각 nginx를 CORS로 쓰는 컬리 환경에서, 비기술자도 접근 차단을 설정하고 클러스터·권한 단위로 세밀하게 제어할 수 있는 AccessBlock 시스템을 업무 RDBMS 의존 없이 재설계한 기록이다.
핵심 포인트- nginx 설정은 인프라팀 의존이 크고 비기술자가 못 다뤄, 기획자·QA·운영도 쓸 수 있는 접근 차단 시스템이 필요했다.
- 메타데이터(무엇을 차단)는 구글시트→BigQuery→Redis로, 실행데이터(언제·누구를)는 API 직접 호출→Redis로 분리했다.
- BigQuery는 작은 쿼리도 수백 ms라 매 라우팅마다 질의하면 성능이 저하돼 Redis 캐싱 + 정확히 3분 주기 동기화 배치로 처리했다.
- 저장 타입을 용도로 분리해 메타데이터는 List, 빈번한 추가·삭제인 실행데이터는 Hash로 저장했다.
- 화면은 VueRouter beforeEach, API는 Spring AOP로 인터셉트하고 클러스터·창고·권한(excludeRoles) 조합으로 차단을 판정한다.
상세 정리- 기존 문제: nginx는 강력하나 인프라팀 의존이 크고, 서버 엔지니어 아닌 사람이 접근 불가하며, 특정 클러스터/센터만 차단하되 슈퍼마스터는 허용하는 세밀 제어가 필요하고, 업무 RDBMS 종속을 제거하려 했다.
- 저장소 선택: 표 형태로 직관적인 구글시트를 입력 UI로, BigQuery로 업무 RDBMS와 독립, Redis로 저지연 캐싱을 구성했다.
- BigQuery 한계: 작은 테이블·간단한 쿼리도 수백 ms라 매 라우팅·API마다 직접 질의하면 지연돼 Redis로 캐싱했고, 기존 N번 호출마다 동기화는 트래픽에 따라 주기 예측이 안 돼 정확히 3분 주기 배치로 교체했다.
- 데이터 분리: 메타데이터는 어떤 path를 차단하는지(path+group, cluster 컬럼 삭제, Redis List), 실행데이터는 언제·누구·어떤 path인지(휘발성이 강해 API 직접 호출, Redis Hash)로 나눴다.
- 실행데이터 필드: id(자동 채번), cluster(빈 값이면 전체), warehouse(센터 단위), excludeRoles(제외 권한 배열), groupName(차단 그룹)으로, 예컨대 평택클러스터·warehouse=null이면 평택 전체를 차단하고 김포는 미차단이다.
- 화면 접근제어: VueRouter beforeEach에서 to.path가 차단 대상인지 확인해 true면 /unavailable로 리다이렉트하고, 로그인·로그아웃·unavailable은 제외한다.
- API 접근제어: Spring AOP로 RestController 요청을 인터셉트하고 @ExcludeAccessBlock 어노테이션으로 제외 대상을 표시하며, 차단 시 InboundServiceException을 던지고 RequestURI·getUserCluster/Warehouse/Roles로 isBlocked를 판정한다.
- 사용법: 구글시트→데이터팀 확장 프로그램으로 BigQuery 업로드→3분 배치가 전체 삭제 후 재저장→Redis List 동기화, 실행데이터는 Swagger/Postman으로 등록(응답 id)·조회·삭제(id로 즉시 해제)한다.
- 트레이드오프: nginx·직접 UI·BigQuery 직접 질의·호출 기반 동기화·데이터 통합을 각각 기각하고, 구글시트+BigQuery·Redis 캐싱·3분 동기화·메타/실행 분리·실행데이터 API 직접 호출을 채택했다.
- 결과·한계: 비기술자도 관리 가능하고 업무 RDBMS와 독립하며 세밀한 권한/클러스터 차단이 가능하나, 코드 전체 공개는 방대해 생략했고 기업 특화라 일반화는 어렵다.
왜 읽나게이트웨이 없이 서비스 점검 모드·접근 차단을 구현해야 하는 백엔드 개발자에게 메타/실행 데이터 분리와 BigQuery·Redis·Spring AOP 설계 레퍼런스.