◉ 학습목표
1. 프록시 서버가 추가된 2-Tier Architecture가 어떻게 동작하는지 설명할 수 있다.
2. 로드밸런서가 필요한 이유와 오토스케일링의 장점을 설명할 수 있다.
3. 다양한 웹 서버의 주요 목적을 설명할 수 있다.
4. NGINX를 사용해 프록시 서버와 로드밸런싱을 구성할 수 있다.
5. VPC를 이용해 안전한 배포 아키텍처를 구성할 수 있다.
- Proxy Server
⦿ 학습내용
☞ 프록시 서버
✔︎ 클라이언트가 서버와 소통할 때, 서버에 바로 접근하지 않고 자신을 통해 서버에 접근할 수 있도록 해주는 일종의 대리 서버
☞ 프록시 서버의 종류
✔︎ Forward Proxy
- 클라이언트 가까이에 위치한 프록시 서버
- 클라이언트를 대신해 서버에 요청을 전달
- 장점
- 캐싱을 통해 빠른 서비스 이용 가능
- 보안 : 서버에게 클라이언트 IP를 숨길 수 있음
✔︎ Reverse Proxy
- 서버 가까이에 위치한 프록시 서버
- 서버를 대신해 클라이언트에 응답을 제공
- 장점
- 분산처리 : 과부하 대비
- 보안 : 클라이언트에게 서버 IP를 숨길 수 있음
- 로드밸런서
⦿ 학습내용
☞ 과부하
✔︎ 하나의 서버에 너무 많은, 혹은 잦은 요청을 보낸다면 서버에 과부하 발생
☞ Scale-Up
✔︎ 물리적으로 서버의 사양을 높이는 하드웨어적인 방법
✔︎ 장점
- 서버의 수를 늘리지 않고 프로그램 구현에 있어 변화가 필요 ❌
✔︎ 단점
- 서버의 사양을 높이는 데에 높은 비용 발생
- 하드웨어의 업그레이드에 한계가 있음
- 사양을 늘린만큼 클라이언트 요청이 많아지면, 여전히 부하 문제 해결 ❌
☞ Scale-Out
✔︎ 서버의 개수를 늘려 하나의 서버에 줄 부하를 분산시키는 방법
✔︎ 장점 : 비교적 저렴한 방법
⭐️ 로드밸런서
- 요청을 여러 서버에 나눠 처리할 수 있도록 교통정리를 해주는 역할
※ 로드 밸런싱
- 여러 서버에 교통 정리를 해주는 기술 혹은 프로그램
☞ 로드 밸런서의 종류
✔︎ 클라이언트의 요청을 어떤 것을 기준으로 분산시키냐에 따라 네 가지 종류로 나뉨
☞ Scale 정리
- 오토스케일링
✅ AWS의 오토스케일링 기반
⦿ 학습내용
☞ 오토스케일링
✔︎ Scale-Out 방식으로 서버를 증설할 때 자동으로 서버(리소스)를 관리해주는 기능
✔︎ 클라이언트의 요청이 많아져 서버의 처리 요구량이 증가하면, 새 리소스를 자동으로 추가
✔︎ 반대로 처리 요구량이 줄어들면 리소스를 감소시켜 적절한 분산 환경 만들어줌
☞ Auto Scaling의 장점
✔︎ 동적 스케일링
- 사용자의 요구 수준에 따라 리소스를 동적으로 스케일링 가능
- Scale-Up 할 수 있는 서버의 수에는 제한 ❌
- 필요한 경우 서버 두 대에서 수백~수만 대의 서버로 즉시 스케일 아웃 가능
✔︎ 로드 밸런싱
- 로드밸런서와 함께 사용하면, 다수의 EC2 인스턴스에게 워크로드(작업량) 효과적 분배 가능
- 사용자가 정의한 규칙에 따라 워크로드 효과적 관리 가능
✔︎ 타겟 트래킹
- 사용자는 특정 타겟에 대해서만 Auto Scaling 가능
- 사용자가 설정한 타겟에 맞춰 EC2 인스턴스의 수를 조정
✔︎ 헬스 체크와 서버 플릿 관리
- 헬스 체크를 하는 과정에서 특정 인스턴스의 문제가 감지되면, 자동으로 다른 인스턴스로 교체
- 특정 서버가 문제가 생기면 나머지 서버가 인스턴스 처리 용량을 유지하기 위해 부족한 만큼 서버를 추가로 실행시키며 서버 플릿 유지
※ 서버 플릿(Fleet) : 다수의 EC2 서버에서 애플리케이션을 호스팅할 때, 일련의 EC2 서버 집합
☞ EC2 Auto Sscaling 활용
✔︎ 시작 템플릿 (Launch Configuration)
- Auto Scaling으로 인스턴스를 확장 또는 축소하려면 어떤 서버를 사용할지 결정해야 함
- AMI 상세 정보, 인스턴스 타입, 키 페어, 시큐리티 그룹 등 인스턴스에 대한 모든 정보를 담고 있음
- 시작 템플릿 대신 시작 구성 생성 가능
- 시작 구성은 EC2 Auto Scaling이 사용자를 위해 생성하는 EC2 인스턴스 유형을 지정한다는 점에서 시작 템플릿과 비슷
- 사용할 AMI의 ID, 인스턴스 유형, 키 페어, 보안 그룹 등의 정보를 포함 시켜 시작 구성 생성
✔︎ Auto Scaling 그룹 생성
- 스케일 업 및 스케일 다운 규칙의 모음
- EC2 인스턴스 시작부터 삭제까지의 모든 동작에 대한 규칙과 정책을 담고 있음
- 스케일링 정책 및 유형에 대해 잘 숙지하고 있어야 함
✔︎ Scaling 유형
- 인스턴스 레벨 유지
- 기본 스케일링 계획으로도 부름
- 항상 실행 상태를 유지하고자 하는 인스턴수의 수 지정 가능
- 일정한 수의 인스턴스가 필요한 경우, 최소/최대 및 원하는 용량에 동일한 값 설정 가능
- 수동 스케일링
- 기존 Auto Scaling 그룹의 크기를 수동으로 변경 가능
- 사용자가 직접 콘솔이나 API, CLI 등을 이용해 수동으로 인스턴스를 추가 또는 삭제해야 함
- 추천하지 않는 방식 🤔
- 일정별 스케일링
예측 스케일링 트래픽
의 변화를 예측 가능
- 특정 시간대 어느 정도의 트래픽 증가 패턴을 파악하고 있으면 유용
ex) 낮 트래픽이 최고치, 밤 트래픽이 거의 ❌
⇒ 낮 시간대 서버 증설, 밤 시간대 스케일 다운하는 규칙 추가
- 동적 스케일링
- 수요 변화에 대응하여 Auto Scaling 그룹의 용량을 조정하는 방법 정의
- CloudWatch가 모니터링하는 지표를 추적하여 경보 상태일 때 수행할 스케일링 규칙 정함
ex) CPU 처리 용량 80% 수준까지 급등한 상태가 5분 이상 지속
⇒ Auto Scaling 작동되어 새 서버 추가하는 방식
- 이와 같은 스케일링 정책을 정의할 때는 항상 스케일 업과 스케일 다운 두 가지 정책을 작성해야 함
- 웹 서버 - TOMCAT, Jetty
⦿ 학습내용
☞ TOMCAT
✔︎ Apache사에서 개발한 서블릿 컨테이너만 있는 오픈소스 웹 애플리케이션 서버
✔︎ 특징
- 자바 애플리케이션을 위한 대표적인 오픈소스 WAS(Web Application Server)
- 오픈소스이기 때문에 라이선스 비용 부담 없이 사용 가능
- 독립적으로도 사용 가능
- Apache 같은 다른 웹 서버와 연동하여 사용 가능
- 자바 서블릿 컨테이너에 대한 공식 구현체
- Spring Boot에 내장되어있어 별도의 설치 과정 필요 ❌
☞ Tomcat 실행 및 의존성 확인
✔︎ 프로젝트 실행 시
✔︎ Tomcat에 대한 의존성 확인 방법
- Intellij 상단 메뉴바의
View
> Tool Windows
> Gradle
클릭
- 서버를 구성하기 위해 추가한
spring-boot-starter-web
모듈(Spring web) 주목 ❗️
☞ Jetty
✔︎ 이클립스 재단의 HTTP 서버이자 자바 서블릿 컨테이너
✔︎ 특징
- 2009년 이클립스 재단으로 이전하며 오픈소스 프로젝트로 개발됨
- 타 웹 애플리케이션 대비 적은 메모리를 사용하여 가볍고 빠름
- 애플리케이션에 내장 가능
- 경량 웹 애플리케이션으로 소형 장비, 소규모 프로그램에 더 적합
☞ Spring Boot 서버 Jetty로 변경
✔︎ build.gradle
파일에서 Tomcat 의존성 제거
implementation ('org.springframework.boot:spring-boot-starter-web') {
exclude module: 'spring-boot-starter-tomcat'
}
✔︎ Jetty 의존성 추가
implementation ('org.springframework.boot:spring-boot-starter-jetty')
✔︎ 재 빌드 후 Spring Boot 실행
※ 이와 같은 방법으로 Netty, Undertow 등 다양한 서버로 변경 가능
- 웹 서버 - NginX
⦿ 학습내용
☞ NginX - Proxy Server
✔︎ Nginx
- 가볍고 높은 성능을 보이는 오픈소스 웹 서버 소프트웨어
- 자바 서블릿 컨테이너 혹은 웹 애플리케이션 서버였던
Tomcat
과 Jetty
와는 다름
- NginX는 웹 서버로 클라이언트에게 정적 리소스를 빠르게 응답하기 위한 웹 서버로 사용
- 특징
- 트래픽이 많은 웹 사이트의 확장성을 위해 개발된 고성능 웹 서버
- 비동기 이벤트 기반으로, 적은 자원으로 높은 성능과 높은 동시성을 위해 개발
- 다수의 클라이언트 연결을 효율적으로 처리 가능
- 클라이언트와 서버 사이 존재하는 리버스 프록시 서버 사용 가능
- 클라이언트와 서버 사이에 배치하여 무중단 배포 가능
✔︎ Spring Boot와 Nginx 연동
① Nginx 설치
$ brew install nginx
② Nginx 실행
$ brew services start nginx
- 실행 확인 :
http://localhost:8080
에 접근
③ Nginx 설정 파일 수정
$ nginx -t
$ nano /opt/homebrew/etc/nginx/nginx.conf
- 설정 파일 수정
④ Nginx 재시작
$ brew services restart nignx
- Nginx 실행 파일이 있는 폴더로 이동하여 다음 명령어 실행
$ nginx -s reload
localhost
(80번 포트 생략 가능) 접속
※ Nginx 종료
$ brew services stop nginx
☞ NGINX - Load Balancer
✔︎ 두개의 스프링부트 서버 실행
./gradlew build
- 빌드 파일 실행 (포트 변경하지 않은 경우 8080번 포트에서 실행)
java -jar sample-0.0.1-SNAPSHOT.jar
- 실행 결과
- 8080번 포트에서 35975번의 PID를 통해 실행됨
- 새 터미널에 다른 포트(8081번 포트)에서 실행
java -Dserver.port=8081 -jar sample-0.0.1-SNAPSHOT.jar
- 8080포트와 다른 PID로 실행됨
- 8080번 포트로 실행한 프로젝트의 PID는 35975
- 8081번 포트로 실행한 프로젝트의 PID는 36084
✔︎ NGINX 설정파일 수정
✅ 이전 실습에서 작성한 내용은 주석처리하거나 삭제 후 진행해야 함 ❗️
http {
upstream backend {
server localhost:8080;
server localhost:8081;
}
location / {
proxy_pass http://backend;
}
}
backend
라는 서버 그룹을 만든 뒤 그룹 자체로 전달하는 구조
proxy_pass
값으로 해당 서버 그룹 설정
localhost
로 접속시 8080번 포트와 8081번 포트가 번갈아 연결
✔︎ 로드밸런싱 결과
localhost
(80번 포트 생략 가능)으로 실행
- 새로고침을 하면 PID가 번갈아가며 나옴
- VPC
⦿ 학습내용
☞ VPC (Virtual Private Cloud)
✔︎ 클라우드 내 프라이빗 공간을 제공함
✔︎ 클라우드를 퍼블릭과 프라이빗 영역으로 논리적으로 분리할 수 있게 함
✔︎ VPC가 없었을 때
- 클라우드에 있는 리소스를 격리할 수 있는 방법 ❌
- 인스턴스들이 서로 거미줄처럼 연결되고 인터넷과 연결되어 시스템 복잡도가 엄청나게 ↑, 의존도 역시 ↑
- 따라서, 유지 관리에 많은 비용과 노력이 필요했음 ...
✔︎ VPC를 분리함으로써 확장성을 가질 수 있고, 네트워크에 대한 완전한 통제권을 가질 수 있음
☞ VPC 이해를 위한 구성 요소와 주요 용어
✔︎ IP Address
- IP : 컴퓨터 네트워크에서 장치들이 서로 인식하고 통신하기 위해 사용하는 특수한 번호
- IPv4, IPv6로 나뉘어 있고, 혼용해 사용 중임
- IPv4 예시
- 실제 형태는 2진수 8자리의 형태
- 각 8bit씩 총 32bit로 구성
- 옥텟(Octet) : 각 8bit, .
으로 구분
- IPv4는 4개의 Octet으로 이루어져 있음
✔︎ IP Address Class
- 이전에는 IPv4에서 호스트가 연결되어 있는 특정 네트워크를 가리키는 8비트의 네트워크 영역(Network Address)과 해당 네트워크 내에서 호스트의 주소(Host Address)를 가리키는 나머지 영역을 구분하기 위해서 클래스(Class) 사용
- 총 5가지(A, B, C, D, E) 클래스로 나뉨
- 그러나 D와 E 클래스는 멀티캐스트용, 연구 개발을 위한 예약 IP이므로 보통 사용되지 않음
- A 클래스
🚨 단, 0.0.0.0
의 경우 자체 네트워크를 의미하기 때문에 제외되고, 127.0.0.0
~ 127.255.255.255
는 자기 자신을 가리키기 위한 목적으로 예약된 IP주소기 때문에 사용 ❌
- B 클래스
- C 클래스
✔︎ CIDR (Classless inter-domain routing)
- 사이더라고 불리며, 클래스없는 도메인 간 라우팅 기법
- 1993년 도입되기 시작한 국제 표준의 IP주소 할당 방법
- IP 클래스 방식을 대체한 방식
- 기존에는 클래스에 따라 정해진 Network Address와 Host Address를 사용해야 했음
- CIDR는 원하는 블록만큼 Network Address를 지정하여 운용 가능
- 예시
- /16
: 첫 16bit를 Network Address로 사용한다는 의미
- 총 2^16인 65,536개의 IP주소를 사용할 수 있다는 네트워크 블록 표현 방식
- 자세한 내용은 나무위키 참고
✔︎ 서브넷 (Subnet)
- 서브네트워크 (subnetwork)의 줄임말로, IP 네트워크의 논리적인 하위 부분을 가리킴
- 서브넷을 통해 하나의 네트워크를 여러 개로 나눌 수 있음
- VPC를 사용하면 필요에 따라 다양한 서브넷 생성 가능
- 퍼블릭 서브넷 : 인터넷을 통해 연결할 수 있는 서브넷
- 프라이빗 서브넷 : 인터넷을 연결하지 않고, 보안을 유지하는 배타적인 서브넷
- VPN only 서브넷 : 기업 데이터 센터와 VPC를 연결하는 서브넷
- 서브넷은 VPC의 CIDR 블록을 이용해 정의되며, 최소 크기의 서브넷은
/28
🚨 주의 : 서브넷은 AZ당 최소 하나 사용 가능 (여러 개의 AZ에 연결되는 서브넷 만들 수 ❌)
※ Tips
- AWS가 확보한 서브넷 중 처음 네 개의 IP주소와 마지막 IP주소는 인터넷 네트워킹을 위해 예약되어 있음
- 가용 IP주소를 계산할 때 항상 기억하고 있어야 함 ❗️ (-5개)
✔︎ 라우팅 테이블 (Routing Table)
- 트래픽의 전송 방향을 결정하는 라우트와 관련된 규칙을 담은 테이블
- 목적지를 향한 최적의 경로로 데이터 패킷을 전송하기 위한 모든 정보를 담고 있음
- 하나의 지점에서 또 다른 지점으로 가기 위한 모든 정보를 제공하기 위한 테이블
- 모든 서브넷은 라우팅 테이블을 지남
- 하나의 라우팅 테이블 규칙을 여러 개의 서브넷에 연결하는 것도 가능
- 서브넷을 생성하고 별도의 라우팅 테이블을 생성하지 않으면 클라우드가 자동으로 VPC의 메인 라우팅 테이블에 연결
⭐️⭐️⭐️ AWS VPC 강의
◉ 느낀 점
☞ 프록시 서버, 로드밸런서, 오토스케일링 등 개념적인 부분과 지루할 때쯤 웹 서버의 Tomcat, Jetty, NginX의 간단한 실습을 진행하면서 오늘 하루도 알차게 보냈다 😊
처음 개념을 읽어볼 때는 이해가 잘 안돼서 집중력도 흐트러졌지만, 자꾸 반복해서 읽다보니 머릿 속으로 대충 그림이 그려져 이해할 만 했다..!!
마지막에 VPC를 학습할 때는 개념적인 부분만을 읽어서 확실히 이해할 수 없었는데, 뒤에 AWS에서 VPC에 관한 유튜브 강의 내용이 첨부되어 있어 이해하는 데에 크게 도움이 되었다.
약 45분 가량되는 강의 내용이라 한번에 빡! 집중해서 들을 수 있을까.. 걱정도 됐는데 AWS 코리아의 양승도님께서 설명하시는 걸 보면서 와... 감탄하면서 잘 들었다 :0 (나도 언젠간 저렇게 멋있는 사람이 되고 싶다 👀)
내일부터는 이제 본격적인 프로젝트를 위한 첫 단계인 웹 애플리케이션 설계 시간이다. 솔로 프로젝트로 되어 있고, 정말 빡세게 준비해야한다.. 나 자신을 믿고 힘내자 🫡
◉ 내일의 키워드
・ 웹 애플리케이션 설계