[삽질 가득 서버 설치기] [Apache + Tomcat] 6 - 이클립스에서 개발한 프로젝트 리눅스에 배포하기

개요

시작하기 전에

  • 커맨드는 $ 표시로 구분하였다.
  • 중요한 내용이 아닌 경우 [참고] 라는 이름으로 별도의 타이틀링을 하였다. 삽질 과정의 주저리로서 무시해도 괜찮은 내용이다.삽질 과정을 모두 기록한 글이기 때문에, 중간 중간 과도하게 상세한 설명이 들어가있다.
  • JDK 설치를 위해서 반드시 진행해야 하는 부분은 [👨🏼‍💻 중요] 표시로 구분하였다. 이 표시만 따라가면 우분투 리눅스에 JDK 를 설치할 수 있다.

지금까지

  • AWS 인스턴스 생성
  • Tomcat 설치 및 설정
  • Apache 설치
  • mod_jk 활용한 Tomcat 과 Apache 연동
  • 원격 파일 제어(업로드, 다운로드) 및 소스코드 원격 제어(수정) 환경 구축
  • JSP 코드를 활용하여 DB 제어하기

이제 하려고 하는 것

  • 동작하는 서버를 구축하기

단, 리눅스(GUI 가 아닌)에서 개발을 진행하기에는 무리가 있으므로, 별도의 운영체제에서 개발을 진행한 경우 프로젝트를 리눅스 서버로 옮겨주어야 한다.

  • 이클립스에서 제작한 프로젝트를 리눅스 서버 환경에서 동작할 수 있도록 배포하기

진행과정 요약

  1. 이클립스 프로젝트 Export 하기(*.war 파일 생성)
  2. WAR 파일 리눅스의 톰캣 Webapps 폴더로 옮겨주기
  3. 톰캣 재시작

참고 블로그

http://withcoding.com/38

 

이클립스 웹어플리케이션 war파일 배포 방법, 톰캣(tomcat)서버 환경 프로그램 배치

자신의 컴퓨터 개발환경(이클립스)에서 JSP나 서블릿으로 프로그래밍을 했으면 실제 사용할 서버에 배포(Deployment)를 해야합니다. 단순한 JSP파일같은 경우에는 그냥 FTP로 파일을 불러와 편집해서

withcoding.com

 

 

 

프로젝트 Export

[👨🏼‍💻 중요]

  1. 이클립스에서 프로젝트명에서 우클릭
  2. Export 에서 War File 선택

War File 이란? : Web application ARchaive

이클립스-export-대화상자-스크린샷
Eclipse War Export 대화상자

Web Project : 프로젝트를 선택한다.

Destination : War 파일을 내보낼 경로를 선택한다.

Target runtime : Optimize for a specific server runtime (특정 서버에 대해 최적화)

Export source files : 소스 파일(*.java) 포함 여부

Overwrite existing file : 존재하는 파일에 대한 덮어쓰기 여부

WAR 파일 리눅스로 이동시키기

[👨🏼‍💻 중요]

FileZilla 를 활용하여 옮겨주도록 하자. (http://coldmater.tistory.com/162 참고)
(이 글에서는 FileZilla 를 사용하였지만, 대안은 많다. scp 명령어를 활용할 수도 있고, MobaXterm 이라는 애플리케이션을 활용할 수도 있다.

2020년에 다시 돌아와 수정하면서

MobaXterm 을 사용하길 권장한다.)

이후에 tomcat 을 재시작해주도록 하자.

[👨🏼‍💻 중요]

$ cd /usr/lopcal/tomcat8/bin/
$ ./shutdown.sh
$ ./startup.sh

webapps 에 옮겨진 *.war 파일은 톰캣을 재시작할 때 자동으로 압축이 풀어지면서 디렉토리가 생성된다.

리눅스-ls-명령어-webapps폴더에서-수행한-결과-스크린샷
tomcat 시작 전의 webapps 디렉토리

이랬던 webapps 의 폴더 내용이 재시작 후 다음과 같이 변화한다.

(portfolio 폴더는 만들어주지 않았지만, war 파일이 저절로 풀리면서 해당 디렉토리가 생성된다.)

리눅스-ls-명령어-webapps폴더에서-수행한-결과-스크린샷
tomcat 시작 후의 webapps 디렉토리

현재 나의 document root 는 ROOT 디렉토리이다. 이제 배포된 앱이 실행될 수 있도록 경로 설정을 해주어야 하는데 다양한 방법들(도큐먼트 루트 변경, 파일 변경, 깃헙 이용 등)이 있을 것이다.

여기서는 링크를 만들어 portfolio 폴더를 ROOT 라는 이름을 가진 링크가 가리키도록 하자.

풀려진 프로젝트명 (나의 경우 "portfolio")의 링크를 ROOT 라는 이름으로 만들자.

$ ln -s portfolio ROOT

(혹시 ROOT 폴더가 다른 용도로 활용되고 있었다면, 기존 ROOT 폴더의 이름을 변경하거나 백업 후 삭제한다.)

(http://coldmater.tistory.com/157ln 명령어 참고)

이후 제대로 동작하는지 확인하자.

기타 추가 작업

DB 연동하기

[👨🏼‍💻 중요]

서버상에서도 윈도우 이클립스 환경에서 동작하던 Database 와 Table 들을 만들어주어야 한다. 따라서, DB 작업시 모든 SQL 정보를 저장하는 방법을 마련하는 것이 좋다고 생각된다.
(

2020년에 돌아온 필자는

DBeaver 라는 애플리케이션이나 HeidiSQL 이라는 애플리케이션을 활용하여 DB 에 접속하여 DB 정보를 제어하길 권장한다. 또는 intelliJ, Eclipse 등의 IDE 에서 DB Tool 을 활용하는 것도 좋다.)

리눅스 MySQL 한글 깨짐

리눅스 서버에서 MySQL 을 운용하면서 한글이 깨지는 현상이 발생했다. 이를 해결하자.
mysql 이 설치된 디렉토리 내부에 my.cnf 파일을 수정해주어야 한다.
참고 : https://nesoy.github.io/articles/2017-05/mysql-UTF8

다음 내용을 my.cnf 에 추가해준다.

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

collation-server = utf8_unicode_ci

init-connect='SET NAMES utf8'

character-set-server = utf8

우리가 만든 테이블은 위 설정을 변경해주기 이전이므로 다른 character-set 을 사용하고 있다. 이를 확인하는 방법은 다음과 같다.

데이터베이스-select-쿼리-수행-결과
필자가 만들어준 데이터베이스("category_coldmater") 테이블과 column 의 정보

NULL 표시는 INT 형이나, DATETIME 형으로 선언된 컬럼들이다.
데이터베이스의 기본 형을 UTF-8 로 변경하지 않고, 테이블 선언시에 (CREATE TABLE) 형을 지정해줄 수도 있다 .
MySQL 한글 매뉴얼 참고

> table_name VARCHAR(20) CHARACTER SET utf8

위와 같이 선언이 가능하다. 따라서, 필자는 character set 을 설정하지 않았기 때문에, 이를 바꿔주는 alter 명령어를 사용하여 character set 을 변경했다.

> ALTER DATABASE category_coldmater DEFAULT CHARACTER SET utf8;

이후 MySQL 을 재시작 해준다.

그런데 역시나 제대로 동작하면 '삽질 가득'이 아니다. 여전히 컬럼의 character set 은 바뀌지 않았고, 이제 아예 한글이 깨져서라도 들어가지 않는 문제가 발생했다.
참고 https://m.blog.naver.com/blackfrost/40168167133

> alter table note_info modify column content varchar(120) character set utf8 collate utf8_general_ci;

MySQL character set 과 collate

여기서 잠깐 궁금증. character set 은 뭐고 collate 는 뭘까?

참고 : http://jinolog.com/programming/mysql/2011/03/21/character-set-and-collation.html

character set 은 데이터가 어떠한 코드로 저장될지를 결정하며,
collate 는 어떤 방식으로 데이터를 비교할지를 결정한다. (collate, 함께 합치다)

카테고리-서비스-수행-모습
'latin1 character set' 일 때에 저장한 한글은 이제 깨져서 돌아오지 않는다. 하지만 새로운 입력은 제대로 받아들여진다.

war 파일의 구조분석

war 파일은 어떤 모양일까?

문득 궁금해졌다. 웹 프로젝트는 어떤 요소들을 포함하고 있고, 이들이 어떤 관계로 동작하게 되는 것일까?
War 파일을 만들면, 기존 IDE 에서 작업하던 프로젝트의 폴더 구조와는 어떤 차이가 있을까?
만약 같다면, 프로젝트의 폴더의 내용을 그대로 옮겨도 정상 작동 하는가?

결론부터 말하자면, jsp 파일은 URL 을 통해 직접 참조가 가능하지만, class(서블릿) 파일은 URL 을 통해서 접근이 불가능하다. 따라서 톰캣의 기능을 활용하여 매핑을 시켜주어야 한다.

아래는 도대체 어떻게 123.123.123.123/NoteLoadingService 라는 URL 을 통해 NoteLoadingService.class 라는 파일에 접근할 수 있는지 그 원리에 대한 추적 과정이다. 쓰고보니 삽질은 삽질답다. 읽지 않는 것이 정신 건강에 이로울까? 모르겠다. 궁금하면 읽어내려보자.

이클립스의 프로젝트 트리 구조는 바로 아래 스크린샷과 같다.

맨 왼쪽 스크린샷은, 이클립스의 다이나믹 웹 프로젝트의 기본 구조이다.
붉은색 하이라이트는 필자가 추가한 파일들을 의미한다.

가운데 스크린샷은, 실제 프로젝트가 저장된 폴더의 구조이다.

폴더구조-변화를-좌우로-배치한-스크린샷
(왼쪽) Eclipse 프로젝트 / (중간) 실제 프로젝트가 저장된 폴더의 구조 / (오른쪽) Export 한 뒤의 war 파일의 구조

위 트리 구조에서 몇가지 차이점을 찾아볼 수 있다. 먼저 하이라이트 된 내용 외에는 모두 프로젝트 매니저가 자동으로 관리하여 생성한 내용이다. class(컴파일된 파일)src(소스) 파일의 위치와 WEB-INF 폴더 가 그것이다.

프로젝트 폴더의 src 폴더는 사라졌다. 프로젝트를 Export 할 때, 소스 파일 포함 여부를 결정할 수 있다.

buildclasses 폴더가 war 파일이 될 때는 WEB-INF 폴더 밑으로 종속되는 것을 확인할 수 있다.
이는 이클립스에서는 패키지로서 관리되던 내용이다.

.settings 폴더는 사라졌다.

META-INF 폴더 내용 변화를 확인해볼 수 있다. war-tracker 라는 파일이 생겼다. 내용은 없었다.

가장 큰 의문이 생겼다. *.war 파일이 가장 단순해진 것이다. 그 이유가 무엇일까?

  • 남을 파일들(웹 관련 파일들)만 남았다. 기타 설정파일들이 모두 사라졌다.
  • 리눅스 서버 상의 디렉토리 구조를 확인하면 위의 초록색 하이라이트는 모두 필자가 추가한 것이다.
  • 웹 관련 파일(html, jsp, css, js)과 class 파일 및 java 파일들
  • 나머지 디렉토리에서 변화가 생겼을거라 추측했지만, 거의 바뀌지 않았다.
  • 다시 정리하지만 주요한 변화는 비어있던 WEB-INF 폴더에 classes 폴더가 옮겨간 것 뿐이었다.

war 파일의 동작방식

그렇다면 war 파일은 어떻게 동작하는 것일까? 특히, 서블릿 매핑은 어떻게 작동하는 것일까?

이를 위해서 다음 글들을 참고하자.

그러나... 왜 필자의 웹앱 폴더에는 web.xml 이라는 파일이 보이지 않는것일까? 답은 간단했다... 프로젝트 생성시 web.xml 의 생성여부에 관한 체크 박스가 있다.

 

조금씩 실마리가 풀리기는 할 것 같다. 내가 만든 프로젝트에는 @ 를 활용한 어노테이션이 존재한다. 하지만 윗 글을 읽어본 결과 web.xml 파일을 의 servlet 설정으로 특정 url을 대상 class 파일에 매핑 시키고 있다.

web.xml-파일-서블릿-클래스와-url-맵핑-설정부분-스크린샷
web.xml 에서 특정 url 을 서블릿 클래스와 맵핑시키는 방법

그리고, 이어 이 servlet 파일의 코드에는 @(Annotation, 어노테이션) 이 없었다는 것을 알 수 있었다.

서블릿-파일-스크린샷
기존 서블릿 파일

결과적으로 서블릿을 매핑시키는 두 가지 방법이 존재한다.
web.xml 파일로 맵핑하는 방법과 Annotation(@)을 활용한 방법

 

톰캣이 WEB-INF 폴더의 web.xml 파일을 참조하여 '서블릿 클래스 명'과 'URL 패턴을 매핑'을 한다고 하니 납득이 간다.

그렇다면 어노테이션 매핑은 어떻게 톰캣이 감지할까?
이를 이해하기 위해서는 어노테이션에 대한 깊은 이해가 추가로 필요할 듯 하다.

어노테이션에 관한여서는 다음 글들을 참고해보자.

일반 개발자로서 어노테이션을 작성하여 사용하는 경우는 굉장히 드물 것이라는 것이 결론. 일단은 초심자로서, 어노테이션을 활용할 수만 있다면 OK다. 그래도 설명해보자면, 어노테이션이 메타데이터를 관리해주는데, Servlet 의 @WebServlet 어노테이션이란, 해당 서블릿 파일을 톰캣이 URL 패턴으 로서 감지할 수 있도록 하는 장치 정도라고 이해하자.

JAVA 5.0부터 @ 으로 시작하는 어노테이션이 지원되었습니다. 어노테이션은 문장이나 문서에 추가적인 정보를 기입하는 것을 말합니다. 자바 프로그램에 영향을 주는 것이 아니라 컴파일할 때 환경 설정을 변경해 줄 것을 알려주는 주석 형태를 말합니다. 이전에는 환경설정을 XML 파일에서 직접 해왔습니다. 하지만 XML 파일을 열어서 일일이 환경 설정하는 일이 번거롭기도 하고 XML 문법을 시간 내어 학습해야만 하기 때문에 개발자가 직접 XML 파일에서 작업하지 않고 자바 코드에서 어노테이션을 사용하는 방식으로 쉽게 환경을 설정하기 위해 자바 5.0에서부터 등장하게 된 것입니다. 어노테이션 등장 덕분에 개발 시간이 단축되었습니다. 

- 성윤정, 《백견불여일타 JSP&Servlet :Eclipse&Oracle》, 로드북, 2014, 72p

로그 확인하기

이클립스 환경에서는 모든것이 정상적으로 작동하였으나, 위에서 언급했던 한글 character set 처리와 같은 문제때문에 리눅스 서버 환경에서는 또 다른 오류가 발생할 수 있다. 만약 브라우저를 통해 오류를 확인할 수 없다면, 이클립스의 콘솔창과 같은 역할을 누가 해 줄 것인가?

tomcat 기본 폴더 내부의 logs 에서 서버의 실행과 관련하여 각종 정보를 확인할 수 있다. 필자는 실행 오류를 catalina.out 파일을 통해서 확인할 수 있었다.

보통 최근 log 는 파일의 맨 마지막 부분에 생기므로 vim 의 단축키를 사용하면 좋다.

G : vim 문서의 맨 마지막으로 이동하기 단축키
gg : 문서의 맨 처음으로 이동하기(1 G 와 동일)

catalina.out 파일에 관한 이슈는 해당 파일의 크기가 무분별하게 커지는 것에 대한 제어인 것 같다. 그 외에도 로그 파일을 어떻게 관리하는게 효율적인지 로그 설정파일과 관련한 로그 제어에 관한 이슈도 눈에 띈다.

tomcat 로그 종류

위 블로그의 글대로 tomcat log 의 종류를 정리해보면 다음과 같다.

  • console log : System.out 과 System.err 의 배수구(?)
  • java logs : java.util.logging 을 기본으로 활용하는 로깅
  • catalina.[date].log : 카탈리나 엔진의 로그들을 공급
  • localhost.[date].log : 더욱 어플리케이션에 관계되어있음
  • access log : request processing time, request method, page hit count, session activity 등에 대한 정보를 분석할 수 있다. 톰캣에 의한 요청 처리 지표를 모으는데 사용될 수 있다.

완성!

이제 드디어 웹페이지가 작동한다! 그동안의 삽질의 결과물을 확인해보자. 그리고 함께 환호하자.

반응형

Designed by JB FACTORY