먼저 이해를 돕기 위해 웹아키텍쳐에 대해 알아보도록 하겠습니다.
3-tier (혹은 N-tier) 아키택쳐가 등장하기 전, 웹 애플리케이션들은 2-tier 아키택쳐를 활용했다. 클라이언트가 직접 서버에 접속하여, 서버의 자원을 활용하는 방식이었으므로 개발이 편리했다. 하지만 2-tier 아키택쳐의 웹애플리케이션은 보안에 취약했고, 유지보수도 어려웠다.
그래서 등장한 것이 3-tiar 아키택쳐이다.
3-tier 아키택처는 웹 서버와 DB를 논리적으로(혹은 물리적으로) 분리했다. DB의 접속은 서버를 통해서만 가능하도록 구성했다. 웹 서버는 클라이언트의 접속과 웹 애플리케이션의 비즈니스 로직, 그리고 DB접근을 담당했다. 더이상 데이터는 관리하지 않았다.
그런데 웹 애플리케이션의 사용자가 많아지니, 웹 서버에 과부하가 걸리기 시작했다. 클라이언트 접속 하나하나에 프로세스가 할당되어야만 했기 때문이다. 이러한 상황에서 등장한 것이 WAS(Web Application Server)이다. 아래의 그림을 참고하자.
각각의 역할은 다음과 같다.
WAS가 웹 애플리케이션 실행을 주관하고, 웹 서버는 서버의 자원 및 클라이언트를 주관한다.
이렇게 클라이언트의 접속관리와 앱 실행을 분리함으로써 여러 클라이언트가 접근해도 비즈니스 로직 처리를 쓰레드로 할 수 있다. (그 결과 동시성 제어가 화두로 떠올랐고, 대부분 프레임워크에서는 이를 지원한다.)
마지막으로, 위 그림의 FLOW를 간략히 정리하면 아래와 같다
① 클라이언트의 웹 브라우저가 HTTP Request를 한다.
② 웹 서버는 WAS에 웹 애플리케이션 실행을 위임한다.
③ WAS는 해당하는 로직을 수행하다가 DB접근이 필요하면 SQL 질의를 한다.
④ 질의에 따른 응답을 보낸다.
⑤ 실행 결과를 반환한다.
⑥ WAS로 부터 받은 결과를 웹 브라우저에 HTTP로 송신한다
정적웹은 편의점, 동적웹은 식당에 비유할 수 있습니다.
라면을 먹으려 할때 편의점은 레시피를 보고 직접 요리해야하지만
식당에서는 요리사 만들어서 줍니다.
즉 편의점처럼 이미 만들어진 상품을 진열대에 놓인것처럼 프로그래머가 미리 작성한 파일을 진열대에 두고 , 필요시 진열대 파일을 주기 때문에 항상 같은 페이지를 보여주는 것이 정적 웹이고,
동적웹은 요청이 들어올때마다 식당에서 데이터를 조회 및 비지니스 로직을 수행하는 등 그때그때 가공하여 제공되는 것입니다.
소개글이나 댓글기능이 없는 블로그에는 정적웹페이지를 , 사용자글이 업데이트 되어야 하는 게시글에는 동적웹페이지를 주로 적용합니다.
동적웹페이지 방식을 이용한 네이버블로그는, 작성자 이름 제목 내용 등을 데이터 베이스에 저장하고 이걸 접속시마다 페이지를 보여주는 방식의 동적블로그를 많이 이용했는데 이럴 경우 데이터베이스를 따로 관리하는것이 까다롭고, 같은 글을 보여주자고 매번 서버가 일을하게 하고 코딩하는것도 일인거죠. 차라리 그 글들을 하나하나 html파일 단위로 잡지처럼 진열해놓는데 훨씬 운영하기 편한 것입니다. 보관도 그냥 그것들을 복사해서 어디다 저장하면 됩니다.
그래서 요즘 개발자들은 jekyll 이나 Hugo같은 정적웹생성 툴로 블로그를 많이 운영합니다.
웹 서버란 HTTP 프로토콜을 기반으로 클라이언트가 웹 브라우저에서 어떠한 요청을 하면 그 요청을 받아 정적 컨텐츠를 제공하는 서버이다.
정적 컨텐츠란 단순 HTML 문서, CSS, 이미지, 파일 등 즉시 응답 가능한 컨텐츠이다.
1) 클라이언트부터 http요청을 받을 수 있습니다.
1) 정적인 컨텐츠 요청시 -> 정적컨텐츠를 제공
2) 동적인 컨텐츠 요청시 -> 클라이언트의 요청을 WAS에 보내고, WAS가 처리한 결과를 클라이언트에게 전달(응답, response)한다.
DB조회나 다양한 로직처리 등을 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 Application Server입니다.
WAS는 Web Server + Web Container의 역할을 모두 할 수 있다.
여기서 컨테이너는 JSP, Servlet을 실행시킬 수 있는 소프트웨어를 말한다.
즉, JSP, Servlet을 구동할 수있는 환경을 제공하여 웹컨테이너 또는 서블릿 컨테이너라고도 불린다.
현재 WAS의 웹 서버도 정적인 컨텐츠를 처리하는 데 성능상 큰 차이가 없다.
WAS의 역할
WAS = Web Server + Web Container
Web Server 기능들을 구조적으로 분리하여 처리하고자하는 목적으로 제시되었다.
분산 트랜잭션, 보안, 메시징, 쓰레드 처리 등의 기능을 처리하는 분산 환경에서 사용된다.
주로 DB 서버와 같이 수행된다.
1 ) 웹애플리션의 비지니스로직 처리와 DB접속 등을 주관합니다.
2 ) WAS도 클라이언트로부터 HTTP요청을 받을 수 있어서 (대부분의 WAS는 Web Server 내장)
3 ) 요청에 맞는 정적 컨텐츠를 제공할 수 있고, 동적컨텐츠를 제공
Tomcat, JBoss, Jeus, Web Sphere 등
server{
root /www/data;
location / {
}
location /images/ {
}
예 ) NginX에 웹서버 설정을 통해 가능합니다. ( Root는 파일 시스템의 디렉토리의 root)
/images/1.jpg요청이 들어오면 "/www/data/images/1.jpa파일을 찾아 제공
Web Server는 로드밸런싱 기능 있어 WAS가 처리해야하는 요청을 여러WAS로 분산처리 할 수 있습니다.
예) NginX config에 여러개의 WAS를 그룹으로 만들어서 루트에 오는것들에 대해서 그룹에서 오는것을 로드밸런싱하게 할수 있습니다.
로드밸런싱하다보면 특정 was에서 동작이 안될수 있어 웹서버에서 주기적으로 http요청을 보내 서버의 상태를 확인기능을 합니다.
예를 들어 특정 url요청에 200응답이 오는지확인 후 오지 않으면 비정상서버로 인지 그 서버로 요청을 전달하지 않게 해 줄 수 있습니다.
Interval 헬스체크를 통해 서버상태를 확인하는 요청을 날리는 주기 (defalt:5ch)
Fails 아래의 경우 3회 연속 실패하면 서버가 비정상이라고 인지 (defalt:1회)
Passes 서버가 다시 복구되어 요청이 2번 연속 성공하면 서버가 정상으로 인지 (defalt:1회)
NginX 설정
location / {
proxy_pass http://backend;
health_check interval =10 fails = 3 passes =2;
}
하나의 서버에서 PHP, JAVA 애플리케이션을 함께 사용할 수 있다.
Spring Boot는 내장된 Tomcat, Jetty, Undertow 등의 서블릿 컨테이너를 사용하여 웹 애플리케이션을 실행할 수 있습니다. 이러한 서블릿 컨테이너는 개발 및 테스트 목적으로는 충분하지만, 운영 환경에서는 다음과 같은 이유로 웹 서버인 Nginx 등의 별도의 웹 서버와 함께 사용하는 것이 일반적입니다.
Spring Boot는 정적 파일을 처리하는데 있어서 웹 서버에 비해 불리한 성능을 가집니다. 정적 파일을 서블릿 컨테이너로 처리하면, 스프링 애플리케이션의 자원을 낭비할 수 있으며, 부하도 증가할 수 있습니다. 따라서, 정적 파일들은 웹 서버에서 처리하여 성능을 향상시키는 것이 좋습니다.
HTTPS를 사용하여 통신할 경우, SSL 인증서 및 암호화 설정이 필요합니다. 이러한 설정은 서블릿 컨테이너보다는 웹 서버에서 수행하는 것이 효율적이며, 보안상의 이유로도 웹 서버를 사용하는 것이 좋습니다.
대규모 서비스의 경우, 여러 대의 서버를 이용하여 로드 밸런싱을 수행하는 것이 일반적입니다. 이 경우, 로드 밸런서 역할을 하는 웹 서버를 별도로 두고,WAS가 처리해야 할 요청을 여러WAS로 분산처리 할 수 있습니다.
웹 서버는 정적 콘텐츠를 캐시하거나 압축 등의 최적화 기능을 제공하여 성능을 향상시킬 수 있습니다. 이러한 기능을 사용할 수 있으며, 서블릿 컨테이너보다 빠른 속도로 응답할 수 있습니다.
따라서, 운영 환경에서는 보안, 성능, 확장성 등을 고려하여, Spring Boot 애플리케이션과 함께 웹 서버를 사용하는 것이 일반적입니다.
[그림 2] 웹 서비스 구조
웹 서비스는 아래와 같이 다양한 구조를 가질 수 있다.
[그림 2]는 3번 구조를 나타낸다. 클라이언트가 웹 서버에 HTTP 요청을 보내면 웹 서버는 정적인 컨텐츠 요청은 바로 응답하고, 동적인 컨텐츠 요청은 WAS에게 넘겨서 처리하고 결과를 WAS에게 받아서 클라이언트에게 넘겨준다.
참고
https://preamtree.tistory.com/39
https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html
김영한 인프런 강의 자료