Skip to content
isdnetworks
Go back

파일명이 같아도 경로가 갈린다

(수정됨)

명품몰에서 원본 상품을 복제한 항목의 이미지가 안 보이는데 원본 쪽은 아무 문제가 없었다. product_images 를 보니 복제본에도 레코드가 있고 filename 도 원본과 같았다.

Table of contents

Open Table of contents

원인 — 파일명이 같아도 갈리는 경로

저장 경로 규칙을 열어 보니 images/{image_id}/{filename} 처럼 이미지 식별자가 경로의 앞자리에 들어가고 있었다. 원본과 복제본은 filename 이 같아도 image_id 가 다르므로 경로가 완전히 갈린다.

실제로 복제본 쪽 경로를 오브젝트 스토리지에서 조회하니 그 아래에 아무것도 없었다. product_images 레코드는 만들어졌는데 실제 파일 복사만 안 된 상태였다.

판단 기준 — 레코드가 있는 것과 파일이 있는 것

MariaDB 관점에서는 완벽히 정상으로 보인다. 레코드가 있으니 조회에 나오고 filename 이 있으니 화면이 주소까지 만들어 낸다.

그 주소가 가리키는 자리에 파일이 없다는 것만 DB 로는 알 수 없으므로 저장소를 직접 봐야 갈린다. 조회 결과가 정상인 것과 대상이 존재하는 것은 다른 질문이었다.

검증 — 대조는 개별 확인으로 한다

두 곳을 비교하는 스크립트를 만들면서 두 가지 방법이 있었다. 버킷을 접두사 단위로 listObjects() 해서 DB 와 대조하는 것과, 각 키를 doesObjectExist() 로 하나씩 확인하는 것이다. 뒤쪽을 골랐다. 이유는 목록은 항목이 많으면 페이지가 잘리고 표시 과정에서 키가 변형될 수 있어서다. 대신 이미지 수만큼 요청이 나가는 것을 감수했다.

그래서 각 키를 하나씩 조회해서 없는 것만 출력하도록 만들었다. 확인 방법이 결과의 신뢰도를 정하는 자리였다.

복구할 때 봐야 하는 네 가지

원본 경로에 파일이 있으면 copyObject() 로 복구되는데 원본만이 아니라 thumb_300.jpg 변환본까지 함께 옮겨야 했다. 컬렉션도 대표 이미지와 추가 이미지 두 갈래로 나뉘어 있었다.

추가 이미지는 sort_order 가 있어서 원본의 몇 번째가 복제본의 몇 번째와 대응하는지도 확인해야 했다. 이름만 같고 순서가 다르면 이미지가 엉뚱한 자리에 붙게 된다.

조치 — 무엇을 완료로 보느냐

복제 함수 ProductService.duplicate() 가 레코드는 직접 만들고 파일 복사는 @Async 작업으로 넘기고 있었다. 그 작업이 실패해도 복제 자체는 성공으로 기록됐다.

그래서 복사 실패를 copy_status 에 기록하게 하고 복제 완료 판정에 파일 존재를 넣었다. 무엇을 완료로 보느냐가 이 문제의 뿌리였고 레코드만 있으면 완료가 아니라는 정의로 바꾼 것이 근본 대응이었다.

정리


Share this post on:

Previous Post
인코딩된 이름이 실제 키가 되는 자리
Next Post
나갔다 오면 사라지던 진행률