_

Always be tactful

멋쟁이사자처럼/정기 세션

[🦁2] Web App & Spring MVC #1

funczun 2025. 3. 21. 03:21
이번 포스트에서는 `웹 애플리케이션 기본 원리`를 다룹니다.

학습 순서
  1. 웹 애플리케이션 기본 원리 📍
  2. 스프링 MVC 동작 원리와 구현
  3. 객체 지향 설계 원칙 (다음 주 예정)

*본 포스트에서 `더보기`는 추가 설명임


📚 세부 학습 순서

  1. 웹 애플리케이션의 기본 원리
    • 웹 애플리케이션
    • 프로토콜 (HTTP, HTTPS)
    • Web Server와 WAS
    • 3계층 아키텍처
    • 스케일링 (아키텍처의 확장)

웹 애플리케이션의 기본 원리

웹 애플리케이션

 

🔹 Web App이란 `클라이언트`와 `서버` 간의 상호작용을 통해 동작하는 애플리케이션이다.

  • 클라이언트: 주로 사용자가 요청하는 `웹 브라우저`
  • 서버: 요청을 처리하는 `웹 서버`와 `WAS`

🔹 웹 애플리케이션은 주로 `HTTP 프로토콜`을 이용하여 데이터를 주고받는다.

  1. 클라이언트(웹 브라우저)가 URL을 통해 서버에 `HTTP 요청`을 보낸다.
  2. 서버는 요청을 처리하고 `HTTP 응답`을 클라이언트에 보낸다.
더보기

사용자가 `https://example.com/login`에 접속하면, 클라이언트는 `HTTP GET` 요청을 보내고, 서버는 `HTML 로그인 페이지`를 응답으로 보낸다.


프로토콜이 뭔데?

 

🔹 프로토콜은 두 시스템 간의 데이터를 주고받는 방법에 대한 `통신 규약`이다.

  • HTTP/HTTPS: 하이퍼텍스트 전송 프로토콜
  • FTP: 파일 전송 프로토콜
  • SMTP: 이메일 전송 프로토콜

🌐 HTTP와 HTTPS 비교하기

항목 HTTP HTTPS
보안 데이터 암호화 없음 데이터 암호화 (SSL/TLS)
속도 빠름 (암호화의 부재) 상대적으로 느림 (암호화로 인한 오버헤드)
포트 기본 포트 80 기본 포트 443
사용처 보안이 중요하지 않은 페이지 (예: 단순 정보 제공) 보안이 중요한 페이지 (예: 로그인, 결제)

HTTP 요청 & HTTP 응답

 

           ▼ HTTP 요청 ▼           

🔹 HTTP 요청은 네 가지 구성 요소로 이루어져 있다.

  • HTTP 메서드: 요청의 목적을 정의하는 것 (*클라이언트가 서버에 어떤 작업을 요청하는지를 나타낸다.)
  • URL: 요청하려는 자원의 경로 (*요청한 데이터의 위치를 지정한다.)
  • 헤더: 요청에 추가적인 메타데이터를 포함하는 부분 (*클라이언트 정보, 콘텐츠 형식, 인증 토큰 등을 전달한다.)
  • 바디: 서버로 보내고자 하는 실제 데이터가 담기는 부분 (*JSON 데이터, 폼 데이터, 파일 등이 본문에 담겨 전송된다.)
POST /users HTTP/1.1            ← 메서드 (POST), URL (/users), 프로토콜 버전 (HTTP/1.1)
Host: example.com               ← 헤더 (호스트)
Content-Type: application/json  ← 헤더 (바디 형식 지정)
User-Agent: Mozilla/5.0         ← 헤더 (클라이언트 정보)
Content-Length: 47              ← 헤더 (바디 길이)

{
  "name": "jun",                ← 바디 (전송할 데이터)
  "age": 27
}

 

🔹 `헤더`는 요청에 대한 추가 정보를 제공하는 것으로, 일부 생략이 가능하다.

  • 서버가 클라이언트 정보를 반드시 알 필요는 없다면 `User-Agent`를 생략할 수 있으며, 응답 형식은 기본적으로 */*로 처리될 수 있기 때문에 `Accept` 역시 생략해도 문제는 없다.
  • Host 헤더는 HTTP/1.1 이상에서 필수로 포함해야 한다. 이는 다수의 서버가 동일한 IP 주소에서 운영되는 환경일 때, 요청을 올바르게 구분하기 위함이다. (User-Agent도 사실상 필수인 느낌이다.)

🔹 `바디`는 메서드에 따라 반드시 필요할 수도, 생략될 수도 있다.

  • POST, PUT, PATCH 요청처럼 서버로 데이터를 전송하는 경우, 당연히 바디가 필요하다.
  • GET 요청은 단순히 서버에서 데이터를 가져오는 것이 목적이기 때문에 바디를 필요로 하지 않는다.
  • DELETE 요청은 데이터들 삭제하는 것이 목적이기 때문에 일반적으로는 바디를 필요로 하지 않지만, 일부 상황에서는 바디를 포함하기도 한다.
GET /products/1 HTTP/1.1    ← 메서드 (GET), URL (/products/1), 프로토콜 버전 (HTTP/1.1)
Host: example.com           ← 헤더 (호스트)
User-Agent: Mozilla/5.0     ← 헤더 (클라이언트 정보)
더보기

📌 HTTP GET 요청 분석

 

[메서드]

GET: 서버에서 데이터를 가져오려고 하는 요청

 

[URL]

/search?q=flowers: search 리소스를 요청하고, 쿼리 파라미터로 q=flowers를 전달함. 즉, "flowers"에 대한 검색 결과를 요청하는 것임.

 

[프로토콜 버전]

HTTP/1.1: 사용된 HTTP 프로토콜 버전

 

[헤더]

ㄴHost: example.com: 요청을 보낼 서버의 도메인 주소

ㄴUser-Agent: Mozilla/5.0: 요청을 보내는 클라이언트의 정보 (브라우저 정보)

ㄴAccept: text/html: 클라이언트가 서버로부터 text/html 형식의 응답을 원한다고 지정

 

[바디]

GET 요청은 데이터를 서버로 보내지 않기 때문에 바디 X

🔹 주로 쓰이는 HTTP 메서드는 다섯 가지다.

  • GET: 서버에서 리소스를 가져오는 요청 (*주로 데이터를 읽을 때 사용한다.)
  • POST: 서버에 새로운 리소스를 생성하는 요청 (*주로 폼 데이터를 전송할 때 사용한다.)
  • PUT: 서버의 리소스를 수정하는 요청
  • DELETE: 서버의 리소스를 삭제하는 요청
  • PATCH: 서버의 리소스를 부분적으로 수정하는 요청

           ▼ HTTP 응답 ▼           

🔹 HTTP 응답은 세 가지 구성 요소로 이루어져 있다.

  • 상태 코드: 서버가 클라이언트의 요청을 처리한 결과를 나타낸 3자리 숫자 코드
  • 바디: 서버가 클라이언트에게 전달하고자 하는 실제 데이터가 담긴 부분 (*HTML, JSON 등이 포함될 수 있다.)
  • 헤더: 서버가 응답과 함께 추가 정보를 제공하는 부분 (*콘텐츠 타입, 캐시 제어 등 메타 정보가 포함될 수 있다.)
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234

<html>
  <head><title>Welcome to My Website</title></head>
  <body>
    <h1>Welcome to My Website</h1>
    <p>This is a sample page.</p>
  </body>
</html>
더보기

📌 주요 상태 코드 (5개 범주, 3자리 숫자)

 

1xx (Informational): 정보성 응답 (요청이 수신되었고 계속 처리 중)

 

2xx (Successful): 요청의 성공적인 처리 완료

    ㄴ200 OK: 가장 일반적인 상태 코드

    ㄴ201 Created: 리소스가 성공적으로 생성되었다.

 

3xx (Redirection): 클라이언트가 다른 위치로 이동해야 한다.

    ㄴ301 Moved Permanently: 요청한 리소스가 영구적으로 다른 위치로 이동되었다.

 

4xx (Client Error): 클라이언트의 잘못된 요청

    ㄴ400 Bad Request: 요청에 오류가 있다.

    ㄴ404 Not Found: 요청한 리소스를 찾을 수 없다.

 

5xx (Server Error): 서버 내부 오류

    ㄴ500 Internal Server Error: 서버에서 문제가 발생하여 요청을 처리할 수 없다.


웹 애플리케이션의 흐름

웹 서비스 구성 요소:
🧑‍💻 [ 클라이언트 ]  →  🌐 [ 웹 서버 ]  →  ⚙️ [ WAS ]  →  🗄️ [ 데이터베이스 ]
사용자가 회원가입을 한다고 가정하고 흐름을 알아보자!

 

1. 클라이언트가 요청을 보낸다.

  • 사용자가 회원가입 폼을 작성하고 `가입` 버튼을 누르면, 브라우저에서 서버로 POST /users 요청을 보낸다. 본 예제에서는 `june`이라는 사람이 가입하는 상황이다.
POST /users HTTP/1.1
Host: example.com
Content-Type: application/json
{
  "name": "June",
  "email": "june@example.com",
  "password": "1204"
}

 

2. 웹 서버가 요청을 처리한다.

  • 웹 서버는 요청을 받아 적절한 WAS로 전달한다.

3. WAS가 요청을 처리한다.

  • WAS는 해당 요청을 Controller에서 받아, Service 계층에서 비즈니스 로직을 수행하고, Repository 계층에서 DB를 조회하고 저장한다.
@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
}

 

4. 리포지토리 계층이 데이터베이스와 상호작용한다.

  • UserRepository가 DB와 연결하여 데이터를 저장한다.
@Repository
public interface UserRepository extends JpaRepository<User, Long> { }

 

5. 서버는 클라이언트에게 응답을 반환한다.

  • 성공적으로 회원가입이 완료되면, 서버는 클라이언트에게 HTTP 응답을 보낸다.
HTTP/1.1 201 Created
Content-Type: application/json
{
  "id": 1,
  "name": "June",
  "email": "june@example.com"
}

 

        ▼ Web Service▼         

더보기

 

  • 클라이언트 (Client)
    • 사용자가 요청을 보내는 역할
    • 예) 웹 브라우저, 모바일 앱, API 호출을 하는 서비스
  • 웹 서버 (Web Server)
    • 클라이언트의 요청을 받아 정적인 HTML, CSS, JS 파일을 제공하거나, WAS로 요청을 전달하는 역할
    • 예) Nginx, Apache
  • WAS (Web Application Server)
    • 동적인 비즈니스 로직을 처리하는 서버
    • 예) Tomcat, JBoss, Jetty, WebLogic
  • 데이터베이스 (Database)
    • 애플리케이션이 데이터를 저장하고 조회하는 곳
    • 예) MySQL, PostgreSQL, Oracle, MongoDB

 

 ▼ Three-Tier Architecture ▼ 

더보기

① Presentation Layer (프레젠테이션 계층)

  • 사용자 인터페이스(UI) 담당 (웹 브라우저, 모바일 앱 등)
  • HTML, CSS, JavaScript 등 프론트엔드 기술 사용
  • 클라이언트는 웹 서버에 HTTP 요청을 보냄

② Application Layer (애플리케이션 계층)

  • 비즈니스 로직을 처리하는 핵심 계층
  • 클라이언트 요청을 받고, 적절한 서비스 로직을 실행한 후 DB에서 데이터를 가져와 응답을 반환함
  • 일반적으로 Spring MVC 같은 프레임워크를 사용
  • 이 계층에서 보통 Controller-Service-Repository 패턴을 사용함

③ Data Layer (데이터 계층)

  • 데이터 저장 및 관리 담당
  • RDBMS(MySQL, PostgreSQL) 또는 NoSQL(MongoDB, Redis) 사용

이미지: https://github.com/rlaisqls/TIL/blob/main/서버/WAS/웹서버와%E2%80%85WAS.md

서버 종류 역할
Web Server 정적인 파일(HTML, CSS, 이미지 등)을 클라이언트에 제공하며, HTTP 요청을 처리한다. Nginx, Apache
WAS 동적인 요청을 처리하고, 애플리케이션 로직을 실행하며 데이터베이스와 연동한다. Tomcat, JBoss, Jetty

WAS는 웹 서버 기능을 포함한다.
그렇다면, 왜 Web Server를 분리해서 사용할까?

 

 `Web Server + WAS` 조합이 필요한 이유는 아래와 같다.

  1. 정적 리소스와 동적 처리를 분리하여 WAS의 부담을 줄인다.
  2. 로드 밸런싱을 통해 여러 WAS로 부하가 분산된다.
  3. SSL/TLS 처리, DDoS 방어 등, 보안이 강화된다.
  4. 다양한 기술 스택을 지원하여 유연한 아키텍처가 가능하다.

웹 서버는 가볍고 빠르게 정적 파일을 제공하는 것이고, WAS는 비즈니스 로직 처리에 집중하기 위해 분리하는 것이다.

더보기

🔍 Web Server와 WAS를 분리하는 이유

 

1️⃣ 정적 리소스 처리 최적화

  • Web Server(Nginx, Apache)는 정적 리소스(HTML, CSS, JS, 이미지 등) 를 빠르게 제공하는 데 최적화됨
  • WAS(Spring Boot, Tomcat, JBoss 등)는 비즈니스 로직을 실행하는 역할을 함
  • 정적 리소스를 WAS에서 처리하면 불필요한 부하 발생 → Web Server가 처리하도록 분리함

2️⃣ 부하 분산 (Load Balancing)

  • Web Server는 클라이언트 요청을 여러 WAS로 분산할 수 있음
  • 트래픽이 많을 때 WAS 여러 대를 둬도 Web Server가 알아서 부하를 나눠줌

3️⃣ 보안 (Security & HTTPS Offloading)

  • Web Server가 SSL/TLS(HTTPS) 를 처리하고, 내부 WAS로는 HTTP 요청을 전달하면 성능 최적화 가능
  • DDoS 공격, SQL Injection 같은 보안 위협을 Web Server에서 1차 차단 가능

4️⃣ 서로 다른 기술 스택 지원

  • Web Server는 PHP, Node.js, Java 등 다양한 기술을 사용할 수 있도록 함
  • 동일한 Web Server에서 여러 WAS(Tomcat, Node.js, Flask 등)를 함께 운영 가능

스케일링,
웹 애플리케이션 아키텍처의 확장

 

애플리케이션의 규모가 커지면 다음과 같은 방식으로 확장이 가능하다.

  1. 로드 밸런서를 추가한다. (*여러 대의 웹 서버 또는 WAS에 부하를 분산하여 처리 성능을 높인다.)
  2. 상품 목록 같이 자주 조회되는 데이터를 DB 대신 Redis 같은 캐시에서 가져와 속도를 높인다. (*API 응답 속도를 향상하고, DB 부하를 줄인다.)
  3. 애플리케이션을 여러 개의 독립적인 서비스로 분리한다. (*MSA에 대한 설명이며, 서비스를 /users, /orders, /payments처럼 분리한다.)
참고로, 서비스 간의 통신은 `REST API`를 사용한다. 관련 내용은 2편에서 알아보자.

'멋쟁이사자처럼 > 정기 세션' 카테고리의 다른 글

[🦁3] 객체 지향 설계: OOP  (2) 2025.03.28
[🦁2] Web App & Spring MVC #2  (2) 2025.03.23
[🦁1] Git & GitHub  (0) 2025.03.14