2025. 12. 15. 18:19ㆍSpring RoadMap/Spring MVC
웹 애플리케이션 이해
김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 듣고 공부한 내용을 정리해본다. 첫 번째 순서는 웹 애플리케이션이 어떻게 돌아가는지 큰 그림을 이해하는 시간이다.
1. 웹 서버와 WAS, 도대체 뭐가 다를까?
웹을 이야기하려면 HTTP를 빼놓을 수 없다. 오늘날의 웹은 HTTP라는 프로토콜을 기반으로 HTML, 텍스트, 이미지, 영상, 그리고 JSON 데이터까지 거의 모든 형태의 데이터를 전송한다.
그럼 서버는 이 데이터를 어떻게 처리할까? 크게 웹 서버(Web Server)와 웹 애플리케이션 서버(WAS)로 나뉜다.
(차이는 내 블로그에 정리해둔 걸 봐도 될 듯 하다 : https://minddokddok.tistory.com/127)
웹 서버 (Web Server)
웹 서버는 정적 리소스를 제공하는 데 특화되어 있다.
- 하는 일: 브라우저가 "HTML 파일 줘", "이미지 줘" 하면 저장된 파일을 그대로 냅다 던져준다.
- 예시: Nginx, Apache
웹 애플리케이션 서버 (WAS - Web Application Server)
WAS는 웹 서버의 기능을 포함하면서, 프로그램 코드를 실행해서 복잡한 로직을 수행할 수 있다.
- 하는 일: 사용자에 따라 다른 화면을 보여주거나(동적 HTML), DB를 조회하거나, 복잡한 계산을 수행한다.
- 예시: Tomcat, Jetty, Undertow
사실 둘의 경계는 요즘 들어 좀 모호하다. 웹 서버도 플러그인을 꽂으면 로직을 실행할 수 있고, WAS도 정적 리소스를 꽤 잘 처리하기 때문이다. 자바 진영에서는 보통 서블릿 컨테이너 기능이 있으면 WAS라고 부른다.
웹 시스템 구성: WEB, WAS, DB
그럼 시스템을 어떻게 구성하는 게 좋을까? WAS 하나로 다 처리할 수도 있지만(WAS, DB 구성), 보통은 웹 서버와 WAS를 분리해서 구성한다(WEB, WAS, DB 구성).
- 웹 서버의 역할: 정적 리소스(이미지, CSS 등)를 처리한다.
- WAS의 역할: 중요한 애플리케이션 로직을 처리한다.

위는 WAS + DB로만 시스템을 구성,
단점?
- WAS가 너무 많은 역할을 담당하여 서버가 과부하될 수 있다
- 가장 비싼 애플리케이션 로직이 정적 리소스 때문에 수행하기 어려울 수 있다
- WAS에 장애가 생길 시 오류 화면도 노출되지 않는다
위와 같은 단점을 방지하기 위해

웹 서버를 따로 두어, 정적 리소스를 처리하게 한다.
이렇게 나누면 효율적인 리소스 관리가 가능하다. 정적 리소스가 많이 필요하면 웹 서버만 늘리고, 로직 처리가 많으면 WAS만 늘리면 된다. 또, WAS는 복잡한 로직을 돌리다 보니 잘 죽는데(?), 이때 웹 서버가 살아있다면 사용자에게 "점검 중입니다" 같은 예쁜 오류 화면이라도 보여줄 수 있다.
2. 서블릿 (Servlet)
자바 웹 개발의 핵심, 서블릿이다. 만약 서블릿이 없다면 우리는 HTTP 요청 메세지를 직접 파싱하고, 응답 메세지를 한 땀 한 땀 만들어야 했을 거다.
서블릿은 이 귀찮은 작업을 대신해주는 기술이다.

클라이언트가 웹 페이지에서 전송 버튼을 누를 경우 아래와 같이 웹 브라우저가 요청 HTTP 메시지를 생성한다

서블릿의 특징?
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
// 애플리케이션 로직 작성
}
}
urlPatterns의 URL이 호출되면 서블릿 코드가 실행된다
- HttpServletRequest: HTTP 요청 정보를 편리하게 꺼내 쓸 수 있게 해준다.
- HttpServletResponse: 응답 정보를 편리하게 입력할 수 있게 해준다.
개발자는 이제 복잡한 HTTP 스펙을 다 꿰고 있지 않아도, 의미 있는 비즈니스 로직에만 집중하면 된다.

- HTTP 요청 시 WAS는 Request, Response 객체를 새로 만들어 서블릿 객체를 호출한다
- 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용한다
- 개발자는 Response 객체에 HTTP 응답 정보를 편리하게 입력한다
- WAS는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성한다
서블릿 컨테이너
톰캣(Tomcat) 같은 WAS를 서블릿 컨테이너라고 부른다. 이 친구는 서블릿 객체를 생성하고, 초기화하고, 호출하고, 끝내주는 생명주기(Lifecycle)를 관리한다.
중요한 점은 서블릿 객체는 싱글톤(Singleton)으로 관리된다는 것이다. 요청이 올 때마다 객체를 새로 만들면 비효율적이니까, 하나만 만들어놓고 돌려쓴다. 그래서 여러 요청이 동시에 같은 객체를 사용하게 되는데, 이때 공유 변수(멤버 변수) 사용에 매우 주의해야 한다. (내 로그인 정보가 다른 사람에게 보일 수도 있다!)
3. 동시 요청 - 멀티 쓰레드 (중요!)
웹 애플리케이션의 핵심 중 하나가 바로 이 멀티 쓰레드 처리다.

쓰레드는 어플리케이션 코드를 실행하는 것으로 서블릿 객체를 호출한다, 자바 main 메서드를 처음 실행하면 main 이라는 이름의 쓰레드가 실행된다.
쓰레드는 한 번에 하나의 코드 라인만 실행하므로 동시 처리가 필요하다면 쓰레드를 추가로 생성해야한다.

- 장점: 동시 요청 처리가 가능하다, 리소스가 허용할 때 까지 처리하므로 리소스를 최대로 활용 가능하다, 하나의 쓰레드가 지연이라도 나머지는 정상 동작한다
- 단점: 쓰레드 생성 비용이 비싸서 고객 요청이 올 때 마다 쓰레드를 생성하면 응답 속도가 느려진다, 컨텍스트 스위칭 비용이 발생한다, 쓰레드 생성에 제한이 없어 요청이 폭증하면 서버가 감당 못하고 죽는다.
해결책: 쓰레드 풀 (Thread Pool) : 요청마다 쓰레드 생성하는 방식의 단점을 보완
그래서 사용하는 게 쓰레드 풀이다. 쓰레드를 미리 일정 개수(예: 200개) 만들어 놓고, 풀(Pool)에 보관한다.

- 요청이 오면 풀에서 쓰레드를 하나 빌려 쓴다.
- 다 쓰면 풀에 다시 반납한다.
- 풀에 쓰레드가 없으면? 대기하거나 거절당한다.
이 방식은 쓰레드 생성/종료 비용을 아낄 수 있고, 요청이 너무 많이 와도 정해진 숫자만큼만 처리하므로 서버가 다운되지 않고 버틸 수 있게 해준다.
실무 팁: 이 쓰레드 풀의 적정 숫자를 찾는 게 성능 튜닝의 핵심이다.
- 너무 적으면: 서버는 놀고 있는데 사용자는 줄 서서 기다려야 한다 (응답 지연).
- 너무 많으면: 메모리 낭비가 심해지고 서버가 터질 위험이 있다.
- 결론: 아파치 벤치(AB)나 JMeter, nGrinder 같은 툴로 성능 테스트를 해보며 적정 값을 찾아야 한다.
다행히 스프링 부트(내장 톰캣)를 쓰면 이 멀티 쓰레드 처리를 알아서 다 해준다. 개발자는 싱글 쓰레드 프로그래밍 하듯 코드를 짜면 된다. (물론 싱글톤 공유 변수는 조심하자!)
4. HTML, HTTP API, CSR, SSR
마지막으로 웹 개발의 렌더링 방식에 대한 용어 정리다.
정적 리소스 & HTML 페이지
- 정적 리소스: 파일 그대로 제공 (HTML, CSS, JS, 이미지).

- HTML 페이지: 서버에서 동적으로 HTML을 생성해서 제공 (JSP, Thymeleaf).

HTTP API
HTML을 주는 게 아니라, 데이터(주로 JSON)만 주는 방식이다.
- 앱(App)이나, React/Vue 같은 웹 클라이언트와 통신할 때 쓴다.
- 서버끼리 통신할 때도 쓴다.

SSR vs CSR
- SSR (Server Side Rendering): 서버에서 HTML을 다 만들어서 브라우저에 "옛다" 하고 던져주는 방식. 전통적인 방식이고 백엔드 개발자의 영역이다 (JSP, Thymeleaf).

- CSR (Client Side Rendering): HTML 껍데기와 데이터만 던져주면, 브라우저에서 자바스크립트로 화면을 직접 그리는 방식. 요즘 트렌드이고 프론트엔드 개발자의 영역이다 (React, Vue).

요즘 백엔드 개발자는 주로 HTTP API를 잘 만들어서 데이터만 깔끔하게 내려주고, 화면은 프론트엔드에서 알아서 그리는 구조를 많이 사용한다. 하지만 어드민 페이지 같은 건 간단하게 SSR로 만들기도 하니 둘 다 알아두는 게 좋다.
요약: 웹 애플리케이션 이해
- 웹 서버와 WAS의 역할: 웹 서버는 이미지나 HTML 같은 정적 파일을 처리하고, WAS는 DB 조회나 계산 같은 동적인 로직을 담당한다.
- 효율적인 시스템 구성: 정적 리소스는 웹 서버가, 중요한 로직은 WAS가 처리하도록 나누는 것이 시스템 안정성과 효율성 면에서 유리하다.
- 서블릿 (Servlet): 복잡한 HTTP 요청과 응답을 개발자가 편리하게 다룰 수 있게 해주는 자바 기술이다. 객체를 하나만 생성해서 공유(싱글톤)하기 때문에 멤버 변수 사용 시 주의가 필요하다.
- 멀티 쓰레드와 쓰레드 풀: WAS는 동시 요청을 처리하기 위해 쓰레드를 미리 만들어 놓는 '쓰레드 풀' 방식을 사용한다. 이 쓰레드 개수를 적절히 설정하는 것이 서버 성능 튜닝의 핵심이다.
- 화면 렌더링 방식: 서버에서 화면을 다 만들어서 주는 SSR(JSP, 타임리프)과, 데이터만 받고 브라우저가 화면을 그리는 CSR(React, Vue) 방식이 있다.
'Spring RoadMap > Spring MVC' 카테고리의 다른 글
| 스프링 MVC 1편 (6), 스프링 MVC 기본 기능 (1) | 2025.12.21 |
|---|---|
| 스프링 MVC 1편 (5), 스프링 MVC 구조 이해 (0) | 2025.12.20 |
| 스프링 MVC 1편 (4), MVC 프레임워크 만들기 (0) | 2025.12.20 |
| 스프링 MVC 1편 (3), 서블릿 · JSP · MVC 패턴 (0) | 2025.12.19 |
| 스프링 MVC 1편 (2), 서블릿 (0) | 2025.12.18 |