Skip to content
isdnetworks
Go back

무상태 환경에서 파일에 쓰면

(수정됨)

현장 담당자가 화면에서 입력한 점검 메모를 저장하는 기능이 배포 대기 중이었다. 코드를 읽다가 저장 위치가 컨테이너 안의 파일인 것을 봤다.

Table of contents

Open Table of contents

배경 — 컨테이너 안 파일에 쓰던 코드

저장 메서드가 FileWriter 로 실행 디렉터리 아래 ./data/notes.json 을 열어 그대로 쓰고 있었다. 읽을 때도 같은 파일을 연다.

운영은 docker run 으로 띄우는 컨테이너 기반이고 인스턴스가 뜨고 지는 구조였다. Docker 공식 문서대로 컨테이너 안에서 만든 파일은 쓰기 가능한 컨테이너 계층에 남고 컨테이너가 없어지면 그 데이터도 남지 않는다. 그러면 그 파일의 수명이 컨테이너의 수명과 같아진다.

원인 — 사라지는 시점과 불일치

재배포하면 새 컨테이너에 그 파일이 없고 docker restart 가 아니라 다시 만들면 마찬가지다. 인스턴스가 둘이면 요청이 어디로 가느냐에 따라 다른 파일을 읽고 쓴다.

입력한 값이 없어지는데 그것도 불규칙하게 없어진다. 사라지는 시점이 배포 주기와 얽혀 있어서 값이 언제 사라질지 사용자 쪽에서 예측할 수 없다.

막힌 지점 — 개발 환경에서는 잘 된다

이 문제가 까다로운 것은 개발 환경에서 잘 돌기 때문이다. 컨테이너가 하나이고 잘 안 죽으므로 입력하고 조회하면 그대로 나온다.

배포 직후에도 잘 된다. 며칠 뒤 다음 배포 때 사라지고 그때는 원인을 저장 방식과 연결하기 어렵다.

해 본 것 — 저장소에 있던 선례

저장소를 뒤져 보니 현장별 담당자 배정을 저장하는 비슷한 기능이 이미 있었다. 그쪽은 MySQL 의 site_settings 표에 site_id 와 key 와 value 로 쓰고 있었다.

이력을 보니 처음에는 로컬 파일이었다가 바뀐 것이었다. 같은 함정을 이미 겪고 해결한 패턴이 저장소 안에 있었으므로 그 SettingsRepository 를 그대로 쓰는 쪽을 골랐다. 이유는 새로 설계할 것 없이 key 만 바꾸면 돼서다. 대신 메모 본문이 value 컬럼의 TEXT 길이 안에 있어야 하는 제약을 감수했다.

조치 — 배포와 저장 방식 전환의 분리

이것을 알기 전에는 이 기능의 남은 일이 배포 하나인 줄 알았다. 실제로는 저장 방식 전환과 배포 둘이었다.

배포만 하면 기능은 보이는데 값이 안 남고 담당자는 매번 다시 입력하게 된다. 작업 목록에 두 줄로 나눠 적은 것이 요점이었는데 한 줄이면 배포만 하고 끝낼 수 있기 때문이다.

같은 검토가 반복될 것이므로 FileWriter 나 Files.write 가 있으면 그 데이터가 재배포 뒤에도 필요한지 묻는 항목을 리뷰에 넣었다. 진짜 임시 파일도 있으므로 임시면 java.io.tmpdir 아래에 두어 의도가 드러나게 했다.

정리


Share this post on:

Previous Post
옮길 것의 명시 목록
Next Post
우리는 중지했는데 저쪽은 재생 중