Home

Published

- 7 min read

[ Network ] 톰캣(Tomcat)구현하기 미션

img of [ Network ] 톰캣(Tomcat)구현하기 미션

🐱 톰캣 구현하기 🐱

총 4주차로 진행되는 톰캣 스터디를 진행했다. 처음 여는 스터디이기도 하고 저도 처음 해보는 거여서 많이 부족한 점도 많았고, 그만큼 얻어가는 것도 많은 스터디였다.

미션은 크게 4단계로 구성되었다.

  1. HTTP 서버 만들기
  2. 로그인 구현하기
  3. 리팩토링
  4. 동시성 확장하기

톰캣 구현을 진행하면서 필요했던 개념들, 그리고 회고를 해보려고 한다.

톰캣 WAS(web application server) ?

톰캣(Tomcat)은 웹 애플리케이션을 실행하기 위한 오픈 소스 웹 서버 및 서블릿 컨테이너이다. 주로 Java Servlet, JavaServer Pages(JSP), 그리고 관련된 기술들을 실행하는 데 사용된다. 톰캣은 Apache Software Foundation에서 개발하고 유지보수하며, 많은 웹 애플리케이션에서 사용되는 안정적이고 경량화된 서버이다.

주요 특징과 역할

  1. 서블릿 컨테이너: 톰캣은 서블릿과 JSP와 같은 Java 웹 컴포넌트를 실행하기 위한 서블릿 컨테이너로서 동작한다. 이런 서블릿 컨테이너는 Java 웹 애플리케이션을 처리하고 실행하는 역할을 수행한다.
  2. 웹 서버: HTTP 프로토콜을 사용하여 웹 페이지 및 웹 애플리케이션을 제공하는 웹 서버로서의 역할도 수행한다. 정적인 컨텐츠를 제공하거나 동적인 요청을 처리하는 데 사용된다.
  3. Java EE 표준 구현체: 톰캣은 Java EE(Enterprise Edition)의 일부 사양을 준수하며, 서블릿, JSP와 같은 기술들을 구현하는 데 사용된다.
  4. 모듈성과 확장성: 톰캣은 모듈화된 구조를 가지고 있어 필요한 기능을 선택적으로 추가하거나 제거할 수 있으며, 플러그인을 통해 기능을 확장할 수 있다.
  5. 가볍고 빠른 실행: 경량화된 구조로 인해 빠르게 실행되며, 단일 사용자부터 대규모 웹 애플리케이션까지 다양한 규모의 프로젝트에 적합하다.

클래스 다이어그램

image

아키텍처 설명

최대한 서블릿의 구조와 유사하게 만드려고 노력했다. 클래스를 기준으로 설명하겠다.

Http11Processor 클래스

  • 주어진 Socket 연결을 처리하고 HTTP 요청 및 응답을 관리한다.
  • run(): process() 메서드를 호출하여 주어진 Socket 연결을 처리한다.
  • process(Socket connection): execute(Socket connection) 메서드를 호출하여 주어진 Socket의 데이터를 처리한다.

HttpRequest 클래스

  • HTTP 요청을 파싱하고 요청 라인, 헤더 및 바디로 나눈다.
  • HttpRequest(InputStream inputStream): 주어진 InputStream에서 HTTP 요청을 읽어와 요청 라인, 헤더, 바디를 초기화한다.
  • getHttpRequestLine(), getHttpRequestHeader(), getHttpRequestBody(): HTTP 요청의 라인, 헤더, 바디를 반환한다.

HttpResponse 클래스

  • HTTP 응답을 생성하고 클라이언트에게 보낸다.
  • HttpResponse(OutputStream outputStream): 주어진 OutputStream으로 응답을 보낼 수 있는 객체를 초기화한다.
  • getResponse(): 헤더와 바디를 조합하여 클라이언트에게 응답을 보낸다.
  • sendRedirect(String redirectUrl): 리다이렉트 응답을 생성하여 보낸다.

Controller 인터페이스 및 구현체

  • HTTP 요청을 받아 처리하는 인터페이스 및 구현 클래스들이다.
  • Controller: HTTP 요청을 처리하기 위한 메서드 service()를 정의한다.
  • 여러 컨트롤러들(예: CreateUserController, LoginController, StaticContentController 등): Controller 인터페이스를 구현하여 요청에 따라 작업을 수행한다.

RequestMapping 클래스

  • 요청된 URL에 따라 적절한 컨트롤러를 선택한다.
  • getController(String requestUrl): 요청된 URL에 맞는 컨트롤러를 선택하여 반환합니다. 요청에 따라 적절한 컨트롤러를 매핑한다.

회고

처음에는 미션 수행만을 위해 코드를 작성했다. 그러다보니 점점 코드가 더러워지고 리팩토링의 필요성을 느꼈다. 하지만 객체지향적으로 작성하려고 생각했을 때, 너무 막막했다. 무엇을 기준으로 클래스를 나누고 작성해야 할지 감도 오지 않았기 때문이다.

그래서 리팩토링을 하지 않고 있다가, 톰캣 서버에 관해서, HTTP 프로토콜의 구조, 서블릿의 구조를 공부했다. 그래서 어느 순간 보니 자연스럽게 어떻게 나눠야 할지 감이 오기 시작했다. 그래서 객체지향적으로 짜기 위해서는 프로그램의 도메인 지식이 상당히 많이 중요하다는 것을 깨달았다.

한가지 아쉬운 점은, 현재 구조는 InputStream을 받아와서 각 클래스에서 파싱을 각각 나눠서 해주고 있다. 하지만 원래 서블릿은 처음 InputStream을 받아와서 파싱을 한 후, 각 클래스에 전달해주는 걸로 알 고 있다. 그래서 시간이 조금 더 있었다면 처음 request를 받을 때 파싱을 모두 하는 클래스를 만들었을 것 같다.