파이썬 웹 애플리케이션을 실행하기 위한 Gateway Interface 서버인 WSGI, ASGI 등에 대해 정리한 적이 있다. 이러한 Gateway Interface 서버는 파이썬으로 구현되어 있어서, Django와 같은 파이썬 웹 프레임워크로 개발된 애플리케이션을 파이썬 모듈로 import 하여 사용할 수 있다. 이는 인터페이스 서버가 동작하는 프로세스 안에서 해당 애플리케이션 코드를 직접 import하여 Python object 또는 callable 형태로 사용한다는 의미이다.
그렇다면 자바에서는 어떨까? 파이썬의 Gateway Interface 서버와 유사하게, 자바에도 Tomcat, Jetty 등의 웹 애플리케이션 서버 (WAS) 가 존재한다. 이들 서버 역시 요청을 받아 자바 애플리케이션을 통해 처리한다. 이 글에서는 자바 WAS 들이 어떻게 동작하고 애플리케이션을 로드하는지 정리해보려 한다.
1. Java Application Server
자바 WAS에는 Tomcat, Jetty, JBoss, JEUS, Web Sphere 등이 존재한다. 이들은 클라이언트로부터 HTTP 요청을 수신하고, 이를 처리하여 응답을 반환하는 역할을 한다. 사용자 세션관리, HTTPS 등과 같은 보안, 데이터베이스 연결, 트랜잭션 처리, 에러와 예외처리, 로깅, 모니터링 등 다양한 기능을 제공해주어 개발자가 비즈니스 로직에 집중할 수 있도록 한다.
자바 WAS인 Tomcat 등은 웹 컨테이너 또는 서블릿 컨테이너라고도 불린다. 그 이유는 자바 웹서비스를 위한 JSP나 서블릿이 동작할 수 있는 환경을 제공하기 때문이다. 서블릿은 Gateway Inteface처럼 자바환경에서 웹서버와 애플리케이션간의 통신을 위한 인터페이스라고 할 수 있다. 자바 웹 프레임워크인 스프링에서는 서블릿을 구현하여 사용하고 있는데, 자바의 WAS들은 이러한 서블릿의 라이프사이클을 관리하고 서블릿객체를 통해 비즈니스 로직을 수행하도록 한다.
2. JAVA 동작원리와 JVM
자바에서 WAS가 어떻게 동작하고 웹 애플리케이션을 어떻게 로드하는지 등에서 알기전에 기본적으로 자바 환경에서 프로그램이 어떻게 실행되는지 알 필요가 있다. 이와 관련해서 자바 환경에서 중요한 부분 중 하나인 JVM에 대한 설명과 함께 자바 프로그램의 동작 원리에 대해서 정리해본다.
JAVA와 JVM
자바 프로그램은 JVM(Java Virtual Machine) 이라는 가상머신 위에서 실행된다. JVM은 자바 바이트코드를 해석하고 실행하며, 메모리 관리, 쓰레드 관리, JIT(Just-In-Time) 컴파일 등 다양한 기능을 제공한다. 컴파일된 자바 프로그램은 어떤 OS 환경에서도 JVM만 설치된다면 플랫폼과 상관없이 독립적으로 자바 프로그램을 실행할 수 있다.
JVM의 구조
JVM의 구조를 간단하게 정리하자면 아래와 같다.
- Class Loader: JVM내로 클래스 파일 (.class) 들을 읽어와서 Runtime Data Area에 저장하는 역할을 한다.
- Excution Engine: 클래스 로더가 읽어온 바이트 코드를 실행하는 역할을 한다. 내부에는 자바 바이트 코드를 명령 단위로 읽어서 실행하는 인터프리터와 바이트 코드를 기계어로 컴파일하여 실행하도록 하는 JIT 컴파일러를 포함하고 있다. 또한 JVM의 메모리 관리를 담당하는 가비지 콜렉터도 포함한다.
- Runtime Data Area: JVM의 메모리 영역
- Heap Memory: 객체 및 클래스 인스턴스가 저장되는 영역
- Method Area: 클래스 메타데이터 (필드, 메서드 정보)와 static 변수 등 클래스 바이트 코드 저장되는 영역
- Stack Memory: 스레드별로 생성되며, 메서드 호출 및 지역 변수를 저장되는 영역
- Native Method Stack: 자바 바이트 코드가 아닌 다른 언어로 작성된 네이티브 코드를 위한 영역
- PC Register: 현재 실행 중인 스레드의 상태 (실행되고 있는 부분, 명령의 주소)를 저장되는 영역.
프로세스와 JVM
자바 프로그램을 실행하면 OS는 새로운 프로세스를 생성한다. 이때 생성된 자바 프로세스에는 JVM이 로드된다. JVM은 클래스 로더를 통해 실행하려는 자바 클래스들을 로드하여 JVM 메모리에 저장하는 등 초기화 작업을 수행하여 자바 프로세스가 동작 가능한 상태가 되도록 한다.
WAS 동작 순서
- 서버 실행 시, JVM이 초기화되며 서버 프로세스가 시작된다.
- 서버는 설정 파일(web.xml, annotations 등)을 참조하여 애플리케이션의 초기 설정 및 리소스를 로드한다.
- HTTP 요청이 들어오면 이를 적절한 Servlet이나 컨트롤러로 매핑하여 처리한다.
3. WAS와 애플리케이션 동작
서버와 애플리케이션의 관계
JAVA WAS들은 대부분 자바 언어로 개발되었다. 그렇기 때문에 해당 서버들도 이전 JAVA 동작원리와 JVM 항목에서 정리한것과 같이 자바 환경에서 실행되며 JVM에 의해 로드되어 동작한다.
서버들은 동작될 때 xml 설정파일이나 어노테이션 정보를 읽어오거나, webapps 디렉토리와 같은 배포 디렉토리에 배포된 .jar, .war 파일을 읽어서 JVM에 로드하여 실행한다. 이를 통해서 WAS와 웹 애플리케이션은 하나의 프로세스안에서, 동일한 JVM 메모리를 공유하며 실행된다. 이때문에 런타임에 별도의 연결없이 메모리 내에서 직접 호출하고, 객체를 주고받을 수 있다.
동작 과정
- 애플리케이션 서버 실행
- 애플리케이션 서버 실행 시 JVM이 초기화되고, 서버가 시작된다.
- 설정 파일을 읽어 서블릿 및 애플리케이션의 정보를 메모리에 로드한다. - 애플리케이션 로드
- 서버는 webapps 디렉토리와 같이 특정 위치에 배포된 WAR/JAR 파일을 분석하고, 애플리케이션 클래스와 리소스를 JVM 메모리에 로드한다.
- 애플리케이션에 정의된 Servlet, Filters, Listeners 등이 초기화된다. - 요청 처리
- 서버는 HTTP 요청을 수신하고, 요청 URL과 매핑된 Servlet을 찾는다.
- Servlet API를 사용하여 요청 객체(HttpServletRequest)와 응답 객체(HttpServletResponse)를 생성한다.
- 해당 Servlet의 메서드(doGet, doPost 등)를 호출하여 요청을 처리한다. - 응답 반환
- Servlet은 요청 처리 결과를 응답 객체에 담아 서버에 반환한다.
- 서버는 이를 클라이언트로 전송하여 요청을 마무리한다.
4. 결론
Tomcat, Jetty 등 자바의 WAS들은 대부분 자바 언어로 개발되어 자바 환경, JVM에서 실행되어진다. 또한 이들은 Servlet API를 사용하여 구현되어 있는데, Servlet을 통해서 요청을 웹 애플리케이션으로 전달하여 비즈니스 로직을 통해 처리하도록 한다. (비동기 기반의 서버인 Netty는 Servlet이 아닌 다른 방식으로 실행되는데, 별도의 글로 정리하는 것이 좋을 거 같아서 이 글에서는 제외한다.)
결론적으로 이들은 하나의 프로세스 내부의 JVM에서 실행된다. 파이썬에서 WSGI/ASGI 기반의 서버가 해당 인터페이스로 Django, FastAPI 등의 프레임워크로 개발된 애플리케이션을 import 하여 사용하듯이, 자바에서도 WAS의 설정을 기반으로 Spring 애플리케이션 등을 로드하여 해당 애플리케이션에 구현된 Servlet 객체들을 호출하여 비즈니스 로직을 수행한다. 이때문에 따로 서버와 애플리케이션 간의 통신을 구현하거나 할 필요없이 Servlet 구현체만 잘 개발하고 서버 설정에 맞춰 애플리케이션 배포를 잘하기만 하면 정상적으로 WAS가 동작할 수 있다.
[Reference]
- https://change-words.tistory.com/entry/Jetty-Tomcat-JBoss-WebLogic-WebSphere-JEUS
- https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html?source=post_page-----91fbebf0eb67
- https://coding-zzang.tistory.com/m/44
- https://doozi0316.tistory.com/m/entry/1%EC%A3%BC%EC%B0%A8-JVM%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EA%B2%83%EC%9D%B8%EA%B0%80
WAS 종류 정리 (Jetty, Tomcat, JBoss, WebLogic, WebSphere, JEUS)
국내에서 아직까지 가장 많이 사용되는 백엔드 언어는 자바(JAVA)입니다. 그 말은 자바로 개발된 웹 애플리케이션이 매우 많다는 의미이고, 그만큼 자바 기반의 WAS(Web Application Server)가 많이 사용
change-words.tistory.com
[Web] Web Server와 WAS의 차이와 웹 서비스 구조 - Heee's Development Blog
Step by step goes a long way.
gmlwjd9405.github.io
[Java] JVM을 파헤쳐보자: 1. 메모리 구조와 멀티스레드
JVM이란? 자바를 공부하는 사람이라면 JVM에 대한 이야기를 많이 들어보았을 것이다. JVM이란 Java Virtual Machine의 약자로, 자바로 작성된 프로그램을 실행시켜주기 위한 가상 머신(가상의 컴퓨터, 컴
coding-zzang.tistory.com
[JAVA] JVM이란? 개념 및 구조 (JDK, JRE, JIT, 가비지 콜렉터...)
JVM이란 무엇인가 Java Virtual Machine의 줄임말. 직역하면 '자바를 실행하기 위한 가상 기계(컴퓨터)'라고 할 수 있다. Java 는 OS에 종속적이지 않다는 특징을 가지고 있다. OS에 종속받지 않고 실행되
doozi0316.tistory.com
'Tech > Spring | SpringBoot' 카테고리의 다른 글
[Spring] Spring 과 Tomcat (0) | 2024.06.11 |
---|---|
[SpringBoot] Logging - 3 (log4j2) (1) | 2024.01.13 |
[Spring] JaCoCo (0) | 2023.02.23 |
[Spring] lombok - @Builder (0) | 2023.01.30 |
[Spring] MapStruct (1) | 2023.01.08 |