파일을 올리고 다음 화면에서 확인한 뒤 저장하는 흐름이 있었다. 확인 화면에서 오래 머물다 저장을 누른 사용자에게 파일을 찾을 수 없다는 오류가 나왔다.
Table of contents
Open Table of contents
어디에 뒀나
업로드 파일을 File.createTempFile() 로 만들고 있었다. 이 함수는 java.io.tmpdir 에 만든다. 기본값이 /tmp 다.
File tmp = File.createTempFile("upload_", ".dat");
request.getSession().setAttribute("uploadPath", tmp.getAbsolutePath());
/tmp 는 시스템이 관리한다. CentOS 6 은 /etc/cron.daily/tmpwatch 가 매일 돈다. 10일 지난 파일을 지운다. 내가 만든 파일인데 그 자리의 규칙은 내가 정하지 않았다.
언제 지워지나
지워지는 조건이 하나가 아니었다. tmpwatch 가 오래된 것을 지운다. 재부팅할 때 비우는 설정도 있다. 디스크가 차면 다른 프로세스가 정리하기도 한다.
세 번째가 예측이 어렵다. Tomcat 과 상관없는 이유로 사라진다. 이번 건은 첫 번째였다. 확인 화면에서 오래 머문 것이 걸렸다.
우리가 관리하는 자리로 옮겼다
globals.properties 의 upload.temp.dir 에 적은 자리에 만들게 바꿨다. 지우는 것도 우리 배치가 한다.
File dir = new File(config.get("upload.temp.dir"));
String name = UUID.randomUUID().toString() + ".dat";
File tmp = new File(dir, name);
crontab 에 Bash 정리 스크립트를 걸어 하루 지난 파일을 지우게 했다. find 의 -mtime +1 로 고른다. 확인 화면에서 오래 머물러도 하루는 안 넘긴다.
그래도 없을 수 있어 그때 보여 줄 것도 정했다. FileNotFoundException 을 그대로 내보내지 않는다. 만료됐으니 다시 올려 달라는 문구로 바꿨다.
쌓이는 쪽과 확인 방법
정리를 넣기 전에는 반대 문제가 있었다. 저장까지 안 간 파일이 쌓였다. ls -1 | wc -l 로 세니 만 개가 넘었다. ext3 는 한 디렉터리에 파일이 많으면 목록 조회가 느리다.
2011/09/26 처럼 날짜별 하위 디렉터리를 쓰게 했다. 정리도 디렉터리 단위라 rm -rf 한 번이면 된다. mkdirs() 로 미리 만들어 둔다.
HttpSession 에 절대 경로를 넣은 것도 고쳤다. 세션이 끊기면 파일은 남고 경로만 없어진다. 아무도 안 쓰는 파일이 자리를 차지한다. UUID 만 세션에 넣고 경로는 규칙으로 다시 만들게 했다. 절대 경로가 세션에 안 들어가니 Tomcat 을 다른 서버로 옮겨도 영향이 없다.
정리가 의도한 것만 지우는지도 봤다. 하루 지난 것이 842개, 오늘 것이 37개였다. 돌린 뒤 37개가 남아야 맞다. 세어 보니 37개였다. 지운 개수가 아니라 남은 개수를 세야 확인이 된다.
정리
java.io.tmpdir는 그 자리의 규칙을 내가 정하지 않는다- CentOS 6 은
tmpwatch가 10일 지난 것을 지운다. 조건이 그것만도 아니다 - 애플리케이션이 관리하는 자리로 옮기고 crontab 정리를 같이 만든다
- 한 디렉터리에 파일이 만 개 넘으면 ext3 에서 목록 조회가 느려진다
HttpSession에 절대 경로를 넣지 않고 UUID 만 넣는다- 파일이 없을 때 다음에 무엇을 해야 하는지가 담긴 문구를 보여 준다
- 정리가 없으면 반대로 쌓이고 디렉터리 조회 자체가 느려진다
- 날짜별 하위 디렉터리를 쓰면 정리를 디렉터리 단위로 할 수 있다
- 세션에 절대 경로 대신 식별자를 넣고 경로는 규칙으로 만든다
- 확인은 지운 개수가 아니라 남은 개수로 한다