Skip to content
isdnetworks
Go back

서버가 늘 때마다 코드를 고쳤다

(수정됨)

시험 서버가 한 대 늘었다. 같은 .war 를 그대로 올렸는데 Tomcat 이 안 떴다. MySQL 주소가 Java 클래스에 문자열로 박혀 있었다. 그 줄을 고치고 다시 빌드해서 올렸다.

Table of contents

Open Table of contents

여섯 군데에 박혀 있었다

grep 으로 찾아보니 한 군데가 아니었다. MySQL 주소와 계정이 한 클래스에 있었다. 업로드 경로는 다른 클래스에 있었다. 문자 발송 주소와 포트는 또 다른 클래스에 있었다.

private static final String URL  = "jdbc:mysql://10.0.0.21:3306/adsvc";
private static final String BASE = "/data/upload/";
private static final String HOST = "10.0.0.35";

주소와 경로와 포트와 계정. 환경이 바뀌면 전부 바뀌는 것들이다. 이런 값을 밖으로 빼는 방법은 프레임워크 공식 문서의 설정 항목을 보고 정했다. 서버를 하나 늘리면 여섯 군데를 고치고 빌드해야 한다. 하나를 빠뜨리면 그 기능만 다른 서버를 본다.

어떤 결과물이 어느 서버 것인지 몰랐다

더 나빴던 것은 빌드된 .war 끼리 구분이 안 된다는 점이었다. 파일 이름이 같고 안에 든 주소만 다르다. 두 개를 나란히 두면 어느 것이 시험용인지 열어 봐야 안다.

한 번은 시험용을 운영에 올렸다. JSP 는 정상으로 떴는데 데이터가 시험 데이터였다. .war 에 환경이 들어가 있으면 그 파일은 한 곳에서만 쓸 수 있는 것이었다.

값을 밖으로 뺐다

환경마다 다른 값을 .properties 로 분리했다. Java 코드에는 키 이름만 남고 값은 파일에 있다. Spring 의 PropertyPlaceholderConfigurer 가 ${db.url} 자리를 채워 준다.

db.url=jdbc:mysql://10.0.0.21:3306/adsvc
upload.base=/data/upload/
sms.host=10.0.0.35

그런데 그 파일을 소스와 같이 두면 .war 에 들어가니 결국 같은 문제가 된다. 서버 바깥 경로에 두고 그 경로를 Tomcat 이 뜰 때 넘기게 했다.

# CATALINA_OPTS
-Dconfig.path=/etc/adsvc/config.properties
<context:property-placeholder location="file:${config.path}"/>

file: 를 안 붙이면 클래스패스에서 찾는다. 밖에 둔 파일은 file: 로 가리켜야 읽힌다.

이러니 빌드 결과물은 어느 서버에나 같은 것이 올라가고 서버에 있는 파일만 다르다.

없는 키와 예시 파일

파일이 밖에 있으니 키가 빠질 수 있다. 이건 Spring 이 이미 그렇게 한다. 키가 없으면 Could not resolve placeholder 를 내고 Context 가 안 뜬다. ignore-unresolvable 을 켜면 그 실패가 사라진다. 켜지 않았다. 접속 정보가 없으면 아예 안 뜨는 편이 낫다. 빈 값이 흘러가면 접속 시점에 엉뚱한 오류가 난다. 그러면 설정 파일을 의심하기까지 시간이 걸린다.

설정 파일이 소스에 없으니 새 서버를 만들 때 무슨 키가 필요한지 알 방법도 없어졌다. 값이 빈 config.properties.example 을 SVN 에 넣었다. 키 목록이 코드와 같이 관리된다. 새 키를 쓸 때 예시 파일에도 한 줄 넣는다.

비밀번호는 예시 파일에도 빈칸으로 두고 실제 값은 서버 파일에만 뒀다. 그 파일은 chmod 600 으로 좁혔다. 주소나 경로는 비밀이라기보다 환경 차이다. 둘을 같은 파일에 두면 파일 전체가 비밀 취급을 받는다. 그러면 환경 차이 부분도 편하게 못 본다.

정리


Share this post on:

Previous Post
검증이 앱 쪽에 있었다
Next Post
몇 개인지부터 세어 봤다