본문 바로가기
오답노트

Tomcat을 외장서버로 사용해보기

by titlejjk 2023. 8. 18.

 

보통 웹 서버를 만들어 본다면 가장 먼저 접하게 되는 서버 프로그램인 아파치 톰캣(Apache Tomcat)

 

이 아파치톰캣은 아파치 재단에서 제공하는 공개 소프트웨어 웹 애플리케이션 서버 (WAS)이다.

톰캣이란 의미는 숫고양이를 의미하는데 개방적이고 참여적인 환경에서 개발되어왔으며 아파치 라이센스 버전2로 배포된다.

이 아파치톰캣 프로젝트는 전 세계의 최고의 개발자들과 협력하기 위한 것이다.

 

 

✋WAS란?!

Web Application Server의 준말로써 웹 응용 프로그램이 설치되어 작동하는 서버 및 이를 위해 설치되는 미들웨어를 말하며, 웹 서버와 구분하여 말해보자면 웹 서버는 단순히 HTTP로 웹 페이지를 보여주는 정적인 역할이라면 WAS는 웹 서버와 연계되어 동적인 로직과 더 무거운 동작을 수행한다.

이중에 아파치 톰캣은 아파치의 웹서버 기능(정적 리소스)에 더하여 톰캣(동적 리소스)를 함께 다루는 서버라 생각하면 쉽다.

 

톰캣은 선 마이크로시스템즈의 소프트웨어 설계자인 제임스 덩컨 데이비슨에 의한 서블릿 참조 구현으로 출발하였다.

그는 이 프로젝트를 오픈소스화 하는 데 도움을 주었으며 선 마이크로시스템즈가 아파치 소프트웨어 재단에 기부하는 데 핵심적인 역할을 했다.

아파치 앤트 소프트웨어 빌드 자동화 툴은 오픈 소스 프로젝트로 톰캣을 만든 것의 부작으로서 개발되었는데, 데이비슨은 처음에 이 프로젝트가 오픈소스가 되기를 바랬고, 많은 오픈 소스 프로젝트들이 O'Reilly와 관련된 책들을 가지고 있었기 때문에 그는 이 프로젝트의 이름을 동물의 이름을 따서 짓기를 원했다. 그는 톰캣이 자신을 지탱할 수 있는 무언가를 상징했다고 생각했기에 톰캣을 생각했다.

 

톰캣의 특징

톰캣은 자바 서블릿 및 자바 서버 페이지 컨테이너 인데, 자바 서블릿은 코드와 비지니스 로직을 캡슐화하고 요청과 응답을 자바 서버에서 처리 하는 방법을 말한다. 자바 서버 페이지는 서버 측 뷰 렌더링 기술이다.

개발자는 서블릿 또는 자바 서버 페이지의 페이지를 작성하고 톰캣이 라우팅 처리를 하도록 하는 기본적인 매커니즘을 가지고 동작한다.

 

현재 Java Persistence API(JPA)는 톰캣의 웹 서버로 포함 되어있는 코요테 엔진을 통하여 다양한 자바 엔터프라이즈사양과 기능을 포함하도록 하여 톰캣을 확장 시켰다.

 

톰캣에는 TomEE라는 확장버전이 있으며, 이는 더 많은 엔터프라이즈 기능을 포함한다.

 

톰캣에는 크게 3가지 컨테이너로 구분 되어있는데

 

  1. Stand-alone servlet containers
    내장된 웹서버의 기능을 사용하는 것이며, 기능 면에서 자바 웹서버의 부분인 서블릿 컨테이너와 자바 근간의 웹 서버를 사용
  2. In-process servlet containers
    서블릿 컨테이너는 웹서버 플러그인과 자바 컨테이너를 구현하며, 웹서버 플러그인은 웹서버의 주소 공간 내에 JVM을 열고 그 안에 자바 컨테이너가 실행되도록 한다. 다중 스레드의 단일 프로세스 서버로써 적당하고 퍼포먼스도 좋지만 확장성 한계라는 단점을 띄고 있다.
  3. Out-of-process servlet containers
    웹서버 플러그인과 웹서버의 외부 JVM에서 실행하는 JAVA컨테이너로 구현했으며, 웹 서버 플러그인과 자바 컨테이너 JVM은 몇몇 IPC를 사용하여 통신 Out-of-process엔진의 반응 시간은 in-process만큼 좋지 않지만, 확장성과 안전성 면이 보다 좋다.

 

현재 톰캣을 설치하기 위한 최소 사전 요구 사항은 JAVA_HOME 환경이 설정된 JDK 1.8이상의 버전을 요구하고 있으며 톰캣은 Apach.org에서 프로젝트의 다운로드 페이지에서 다운 받을 수 있다.

 

이 외에 상용 WAS제품 보다도 가볍고 빠른 성능을 제공하며 이러한 장점으로 인해 WAS제품으로써 세계에서 가장 많이 사용되는 제품 중하나이다.

 

Tomcat Architecture

 

지금 내가 가장 많이 쓰고 있는 Spring Framework의 특징 중 하나가 톰캣 서버가 내장되어있다는 것인데, 톰캣 내장 서버가 자동 설정의 일부기이 때문에 스프링 부트에서는 톰캣과 서블리 서버가 자동으로 설정되어 있다.

즉 추가설정이 있지 않는한 스프링부트 애플리케이션을 실행하면 톰캣이 생성되고 서블릿이 추가되면서 애플리케이션이 동작하게 된다.

 


약 2주전에 멘토님께서 내주신과제가 내부 톰캣이 아닌 외부 톰캣을 사용해보라고 내주신 과제가 있었다.

사실 이전에 내장톰캣으로 딱히 문제점이 없어보였는데 왜 쓰라고 하셨을까 생각을 해보다 이번 기회에 톰캣에 대해서 찾아보고 외장 톰캣과 내장 톰캣의 다른 점을 찾아보게 되었다.

 

먼저 설치전 어떠한 장점이 있을까 하다가 찾아본 것을 정리해보자면 아래와 같다.

 

  1. 버전제어
    외장 서버를 사용하면 톰캣 버전을 직접 제어할 수 있다. 애플리케이션의 요구 사항에 맞게 적합한 버전을 선택가능
  2. 성능 최적화
    외장 서버를 사용한다면 서버 구성을 더 세밀하게 제어할 수 있다. 성능 최적화를 위해 필요한 구성 변경이 용이
  3. 다중 애플리케이션 배포
    하나의 톰캣 인스턴스에 여러 애플리케이션을 배포할 수 있어 리소스를 더욱더 효율적으로 사용이 가능하다.
  4. 보안강화
    외장 서버를 사용하면 보안 설정을 더 세밀하게 제어가 가능하며, 보안 요구 사항에 맞게 서버 구성이 가능하다
  5. 독립적인 관리와 유지보수
    서버와 애플리케이션을 분리하여 각각의 독립적으로 관리하고 유지보수가 가능해져 유연성이 향상된다
  6. 환경의 일관성
    개발부터 테스트 그리고 프로덕션까지 다양한 환경에서 동일한 서버 설정을 사용하면서, 환경 간 일관성 유지에 도움이 된다.

그렇다면 딱!

다른 부분은 무엇이 있을까?
대표적으로 내장톰캣으로는 할 수 없지만 외장 톰캣으로 가능한 기능 바로 톰캣의 Virtual host기능이다.

https://thxwelchs.github.io/EmbeddedTomcat%EA%B3%BCTomcat%EC%9D%98%EC%B0%A8%EC%9D%B4/

위 처럼 도메인 host에 따라 각각의 다른 루트 컨텍스트를 갖게하여 하나의 웹 애플리케이션 배포만으로 여러 애플리케이션을 운영하는 것처럼 할 수 있는것이 Virtual host기능이다.

👉여러 애플리케이션을 하나의 포트로 서비스 할 수 있다.

 

내장 톰캣으로 실행하는 스프링부트 애플리케이션은 그 자체가 하나의 프로그램으로 서블릿컨테이너가 하나의 포트를 독자적으로 가지고있어 여러 호스트를 분기 할 수 있는 기능이 있긴하지만 사용하기 매우 복잡하다.

 

외장 톰캣의 저러한 기능이 마냥 장점이라고 보기는 어렵다.

왜냐하면 굳이??

virtualHost라는 기능은 일종의 "웹서버"의 기능으로 WAS의 구분(?)에서는 조금 어긋나는 범위이다.

그렇다면 실제 웹서버를 사용하고 WAS는 서블릿 컨테이너의 역할만 하게 구상하고 중간에 웹서버의 역할을 하는 방법은 없을까?

 

바로 엔진엑스(Nginx)와 톰캣(Tomcat)

웹 서버인 엔진엑스와 웹 애플리케이션 서버 톰캣이 서로 다른 역할을 수행하며, 상호 보완적인 관계를 가질 수 있다.

 

엔진엑스

  • 웹서버
    정적 파일(HTML, CSS, JS, 이미지 등)을 직접 클라이언트에 제공한다.
  • 리버스 프록시
    클라이언트의 요청을 내부적으로 처리해야하는 경우(동적 콘텐츠 처리)해당 요청을 톰캣과 같은 애플리케이션 서버로 전달
  • 로드 밸런싱
    여러 톰캣 인스턴스가 있을 때, 부하 분산을 통해 성능과 안정성을 향상
  • SSL/TSL처리
    보안 연결을 위한 SSL/TLS핸드쉐이크 처리

대략적인 엔진엑스의 기능은 위와 같다.

 

정적 파일 처리의 엔진엑스 동적 컨텐츠 처리 톰캣의 상호 작용으로는

클라이언트가 정적 파일을 요청하면 엔진엑스가 직접 응답하며, 클라이언트가 동적 콘텐츠를 요청하면 엔진엑스는 요청을 톰캣으로 전달, 톰캣은 요청을 처리한 후 응답을 엔진엑스로 반환하고 엔진엑스는 최종 응답을 클라이언트로 전달한다.

 

이러한 과정은

정적과 동적 콘텐츠의 처리를 분리시켜 각각에 최적화된 성능을 제공할 수 있어 성능 최적화가 향상되며, 다양한 웹 애플리케이션 서버와 연동이 가능해지고, 구조 변경이나 확장이 용이해진다. 또한 엔진엑스가 외부와의 직접적인 연결을 담당하므로, 내부 네트워크와 톰캣을 보호할 수 있다.

 

 


 

외장톰캣을 사용해보기

를 해보기 전에 먼저 jar와 war의 차이점을 알고가자.

JAR(Java Archive)

.jar는 일반 Java 애플리케이션, 라이브러리, 유틸리티 등을 패키징하는데 사용되며 클래스 파일, 리소스 파일, 메타데이터 등을 포함하여, 특별한 웹 관련 디렉토리가 없다. 보통 스탠드 얼론 애플리케이션, 라이브러리, CLI도구 등에서 사용되며,

WAR(Web Application Archive)는

웹 애플리케이션을 패키징하는데 사용한다. 쉽게 말해 웹 애플리케이션에 필요한 클래스파일, JSP,HTML,JavaScript,이미지 등등의 리소스, 그리고 웹 애플리케이션 서버에서 인식할 수 있는 디렉토리 구조와 메타데이터들을 포함한다.

학원 수업에서 사용했었던 디렉토리 "WEB-INF"폴더에 "web.xml"과 같은 설정 파일을 포함하면서 이폴더 내에서 라이브러리와 클래스를 관리한다. 보통의 웹 서비스, 웹페이지 등 웹 관련 프로젝트에서 사용하는데

 

외장 톰캣과 WAR파일은 웹 애플리케이션의 배포와 실행에 있어 밀접한 관계를 가지고 있다.

패키징된 웹 애플리케이션을 호스팅하고 실행하는 역할을 하며, 이를 통해 유연하고 효율적인 웹 서비스 운영이 가능해진다.

이 구조를 사용하면 웹 애플리케이션의 배포와 관리가 더욱 효율적이게 될 것이다.

 

war는 외장 톰캣으로만 실행이 가능하다.

 

war 빌드

구성환경
MacBook M1Pro AppleSilicon
Java 11
Spring Boot 2.7.14
IDE intelliJ Ultimate
build Gradle

 

1. Sprign Boot Project WAR패키징 준비
먼저 "build.gradle"파일 수정을 해준다.

plugins {
	id 'org.springframework.boot' version '2.7.14'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'war'
}


group = 'com.project'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '11'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.3.1'
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'

}




tasks.named('test') {
	useJUnitPlatform()
}

2. Main Class 수정
Spring Boot애플리케이션의 메인 클래스를 SprinBootServletIntitializer의 서브 클래스로 만들어준다.

package com.project.project;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class ProjectApplication extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(ProjectApplication.class, args);
	}

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
		return application.sources(ProjectApplication.class);
	}


}

3. WAR파일 빌드

intelliJ에서 Gradle탭을 사용하여 "build"작업을 실행한다.

 

4. 외장톰캣 설치 및 설정

내가 사용하는 OS와 환경에서는 zip 또는 tar.gz를 다운 받아야한다.

 

5.Java와 톰캣 연동확인

 

설치한 JDK와 톰캣이 올바르게 동작하는지 확인하는 작업을 진행해보겠다.

권한해제만 10분..ㅠㅠ

 

6. WAR파일 찾기
intelliJ에서 Gradle로 프로젝트를 빌드한 경우 "build/libs"디렉토리에서 WAR파일을 찾을 수 있다. 찾은 WAR파일을 톰캣 설치 경로의 'webapps'디렉토리로 복사해준다.

서버와 통신은 가능한 것으로..

 

 

출처
https://thxwelchs.github.io/EmbeddedTomcat%EA%B3%BCTomcat%EC%9D%98%EC%B0%A8%EC%9D%B4/

댓글