이번 포스트에서는 `웹 애플리케이션 기본 원리`를 다룹니다.
학습 순서
- 웹 애플리케이션 기본 원리 📍
- 스프링 MVC 동작 원리와 구현
- 객체 지향 설계 원칙 (다음 주 예정)
*본 포스트에서 `더보기`는 추가 설명임
📚 세부 학습 순서
- 웹 애플리케이션의 기본 원리
- 웹 애플리케이션
- 프로토콜 (HTTP, HTTPS)
- Web Server와 WAS
- 3계층 아키텍처
- 스케일링 (아키텍처의 확장)
웹 애플리케이션의 기본 원리
웹 애플리케이션
🔹 Web App이란 `클라이언트`와 `서버` 간의 상호작용을 통해 동작하는 애플리케이션이다.
- 클라이언트: 주로 사용자가 요청하는 `웹 브라우저`
- 서버: 요청을 처리하는 `웹 서버`와 `WAS`
🔹 웹 애플리케이션은 주로 `HTTP 프로토콜`을 이용하여 데이터를 주고받는다.
- 클라이언트(웹 브라우저)가 URL을 통해 서버에 `HTTP 요청`을 보낸다.
- 서버는 요청을 처리하고 `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) 사용

서버 종류 | 역할 | 예 |
Web Server | 정적인 파일(HTML, CSS, 이미지 등)을 클라이언트에 제공하며, HTTP 요청을 처리한다. | Nginx, Apache |
WAS | 동적인 요청을 처리하고, 애플리케이션 로직을 실행하며 데이터베이스와 연동한다. | Tomcat, JBoss, Jetty |
WAS는 웹 서버 기능을 포함한다.
그렇다면, 왜 Web Server를 분리해서 사용할까?
`Web Server + WAS` 조합이 필요한 이유는 아래와 같다.
- 정적 리소스와 동적 처리를 분리하여 WAS의 부담을 줄인다.
- 로드 밸런싱을 통해 여러 WAS로 부하가 분산된다.
- SSL/TLS 처리, DDoS 방어 등, 보안이 강화된다.
- 다양한 기술 스택을 지원하여 유연한 아키텍처가 가능하다.
웹 서버는 가볍고 빠르게 정적 파일을 제공하는 것이고, 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 등)를 함께 운영 가능
스케일링,
웹 애플리케이션 아키텍처의 확장
애플리케이션의 규모가 커지면 다음과 같은 방식으로 확장이 가능하다.
- 로드 밸런서를 추가한다. (*여러 대의 웹 서버 또는 WAS에 부하를 분산하여 처리 성능을 높인다.)
- 상품 목록 같이 자주 조회되는 데이터를 DB 대신 Redis 같은 캐시에서 가져와 속도를 높인다. (*API 응답 속도를 향상하고, DB 부하를 줄인다.)
- 애플리케이션을 여러 개의 독립적인 서비스로 분리한다. (*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 |