1.2.3 서버란?

import java.net.ServerSocket;
import java.net.Socket;

public class WebServer {

    public static void main(String[] args) {
        new WebServer().run();
    }

    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true) {
                try {
                    Socket client = serverSocket.accept();
                    new Thread(() -> handleClient(client)).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void handleClient(Socket client) {
        // (1) 클라이언트의 요청 읽어오기
        // (2) 클라이언트의 요청에 맞는 작업 수행하기
        // (3) 클라이언트에게 응답 작성하기
        // (4) 소켓 닫기
    }
}

서버는 프로그램이다. 이 프로그램은 지정된 포트, 8080포트에 소켓을 열어 클라이언트가 연결할 때까지 무한 대기하며 기다린다. 그러다가 클라이언트가 연결하면 해당 클라이언트 소켓에서 요청을 받아와 수행하고 응답을 작성해 전달한다.

서버에서 클라이언트의 요청을 읽어올 때 또는 응답을 작성할 때 파일을 주고 받으면 FTP File Transfer Protocol 서버가 되고, 하이퍼텍스트 트랜스퍼 프로토콜을 사용한다면 HTTP 서버가 되는 것이다.

 

1.2.4 정적 웹 서버

Static Web Server란 HTTP 서버 중에서도 리소스 파일을 리턴하는 서버를 의미한다.

서버 호스트가 8080에서 실행하고 있는 로컬 호스트라고 가정하면, localhost:8080/file.html HTTP 요청을 서버로 보내면 정적 웹 서버인 서버는 지정된 디렉토리 경로에서 file.html를 찾아 그 내용을 HTTP 응답 바디에 넣어 전송한다.

이때, 서버는 해당 html 파일에 아무 작업도 하지 않고 파일을 있는 그대로 리턴한다. 그래서 정적 Static Web Server이다.이런 정적 웹 서버의 예로 아파치, Nginx 등이 있다. 아파치, Nginx를 설치하고 지정된 경로에 원하는 리소스 파일을 저장하면 자동으로 해당 리소스는 웹 서버를 통해 접근할 수 있다.

더보기

질문 주제: 정적 웹 서버의 동작 원리에 대한 추가 설명

정적 웹 서버는 HTML, CSS, JavaScript, 이미지, 폰트, 동영상 등 변하지 않는 정적인 파일을 클라이언트에 제공하는 서버다. 여기서 "정적(static)"이라는 뜻은, 서버가 파일의 내용을 실시간으로 처리하거나 조작하지 않고, 저장된 그대로 응답한다는 뜻이다.

🔧 동작 과정

  1. 클라이언트 요청: 브라우저가 localhost:8080/file.html로 요청을 보낸다.
  2. 서버 응답: 웹 서버(Apache, Nginx 등)는 설정된 루트 디렉토리에서 file.html을 찾아 그대로 읽는다.
  3. 전송: 읽은 파일 내용을 HTTP 응답 바디에 담아 브라우저로 전송한다.
  4. 브라우저 렌더링: 클라이언트는 받은 HTML을 브라우저에서 렌더링한다.

📁 정적 파일이 저장되는 위치

서버는 Document Root 또는 Web Root로 불리는 특정 디렉토리를 기준으로 정적 파일을 찾는다.

예시 (Apache 기준):

/var/www/html/
  • 여기에 index.html을 두면 localhost:8080/index.html로 접근 가능.

⚙️ 주요 특징

속도 파일 처리 없이 곧바로 응답하므로 빠르다
보안 서버 측 코드 실행이 없으므로 보안 이슈 적음
확장성 CDN과 결합 시 수천만 사용자에게도 대응 가능
제약 동적인 데이터 처리나 로그인/DB 연동은 불가능

 

1.2.5 동적 웹 서버

동적 웹 서버는 파일을 있는 그대로 리턴하지 않는다. 동적 웹 서버는 요청을 처리한 후 처리한 결과에 따라 응답 바디를 재구성하거나 HTML 템플릿 파일에 결과를 대체해 보낸다.

위 그림을 통해 동적 웹 서버의 예를 확인해 보자. 클라이언트는 요청에 요청 매개변수를 보낼 수 있다. 그림에서는 name=Engineer라는 매개변수와 값을 보낸다. 이를 확인한 서버는 요청과 매개변수에 맞는 작업을 수행한 후 그 자리에서 html 파일을 구성하거나 템플릿 html 파일에서 적절한 값을 대체하는 방식으로 html을 구성해 리턴한다. 따라서 어떤 클라이언트가 요청하든 같은 응답을 리턴하는 정적 웹 서버와 달리 동적 웹 서버는 클라이언트가 누군지, 어떤 매개변수를 보내는지에 따라 같은 요청이라도 다른 응답을 받을 수 있다.

각 요청과 매개변수에 따라 로직을 작성하는 것이 대부분의 백엔드 개발자가 해야 할일이다. 그러나 유추할 수 있듯이 비즈니스 요구사항에 따라 이 로직은 변한다. 그러므로 개발자들은 아파치나 Nginx 같은 서버 프로그램을 사용하지 못한다. 그렇다면백엔드 개발자들은 처음부터 끝까지 소켓 프로그래밍, HTTP 파싱, 스레드 풀 관리 등모든 것을 새로 다 작성해야 한다는 말인가?다행히 자바 프로그램 중 동적 웹 서버 구현을 도와주는 프로그램이 있다. 바로 서블릿 엔진이다. 아파치 톰캣이 서블릿 엔진에 해당한다.

 

1.2.6 자바 서블릿 컨테이너/엔진

서블릿 컨테이너 또는 서블릿 엔진서버 프로그램이다. 개발자들은 서블릿 엔진을 설치한 후 서블릿 엔진에게 자기가 개발한 비즈니스 로직, 즉 클래스 파일과 해당 클래스 파일을 어느 요청에서 실행해야 하는지 알려줘야 한다. 서블릿 엔진이 이해할 수 있는 형태로 클래스 파일을 작성해야 한다. 구체적으로 서블릿 엔진이 이해할 수 있는 클래스란 javax.servlet.http.HttpServlet 의 상속받는 서브 클래스를 의미한다.

⭐ 스프링 부트도 내부적으로는 서블릿 엔진의 사용을 위해 서블릿을 상속 및 구현한다.

더보기

서블릿 컨테이너(Servlet Container) 또는 서블릿 엔진(Servlet Engine)은 Java 기반 웹 애플리케이션을 실행할 수 있는 서버 프로그램으로, 클라이언트의 HTTP 요청을 받아서 Java Servlet 클래스를 실행하고 응답을 반환하는 역할을 수행한다.

🔧 서블릿 컨테이너의 핵심 역할

요청 수신 클라이언트로부터 HTTP 요청을 받아들이고 적절한 서블릿에 매핑
서블릿 생명주기 관리 init(), service(), destroy() 메서드를 호출하여 서블릿 인스턴스 관리
멀티스레드 처리 클라이언트 요청마다 새로운 스레드 생성하여 병렬 처리 가능
HTTP 프로토콜 처리 HTTP 요청 파싱 및 응답 생성 기능 제공 (HttpServletRequest, HttpServletResponse)
보안, 인증 지원 필터(Filter), 보안 제약 설정 등을 통해 요청 제어 가능
로깅 및 에러 처리 로그 기록 및 예외 처리 메커니즘 제공

🏗️ 서블릿 컨테이너 구조

  1. 웹 서버 역할
    • HTTP 요청을 수신
    • 요청 URL에 따라 서블릿으로 라우팅
  2. 서블릿 매핑
    • web.xml 또는 애노테이션(@WebServlet)을 통해 어떤 URL이 어떤 서블릿에 매핑되는지 설정
  3. 서블릿 실행 흐름
클라이언트 -> HTTP 요청 -> 서블릿 컨테이너 -> HttpServlet 서브 클래스 -> 응답 반환

📁 실무에서의 구조 예시

MyWebApp/
├── WEB-INF/
│   ├── web.xml              ← 서블릿 매핑 정보
│   └── classes/
│       └── com/example/MyServlet.class  ← HttpServlet 상속 클래스
<!-- web.xml 예시 -->
<servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.example.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>

🌐 대표적인 서블릿 컨테이너

Apache Tomcat 가장 널리 쓰이는 오픈소스 서블릿 컨테이너
Jetty 가볍고 임베디드 가능하여 많이 쓰임
Undertow WildFly 기반, 비동기 처리에 강점
GlassFish Java EE 참조 구현 서버로, 서블릿 포함

+ Recent posts