여태껏 spring과 spring boot를 이용해서 각종 프로젝트를 진행해오면서 정작 spring과 spring boot에 대해 자세히 알지는 못하다는 생각이 들었습니다. 그래서 spring 과 spring boot가 어떻게 도입되게 되었는지 그 역사부터 작동원리에 대해 한번 풀어보고자 합니다.
spring에 대해서 알기 전에 spring이 도입되기 전까지의 과정에 대해서 알아볼 필요가 있습니다.
태초의 웹(Web)은 연구자들 간의 정보 공유를 위한 플랫폼으로 시작되었는데 그 원형인 월드 와이드 웹은 1989년 팀 버너스 리(Tim Berners-Lee)에 의해 고안되었습니다. 웹이 탄생하기 전, 연구기관이나 대학교 간 정보 공유는 주로 이메일이나 파일 전송 방식에 의존했습니다. 그러나 이 방식은 구조적이지 않고, 대규모의 데이터를 일관성 있게 관리하거나 효율적으로 검색하는 데 한계가 있었습니다.
팀 버너스 리는 유럽 입자 물리 연구소(CERN)에서 연구원들이 전 세계의 다른 연구자들과 빠르게 정보를 공유할 수 있는 시스템을 구상했습니다. 그의 비전은 모든 문서를 하나의 시스템에서 연결하고, 쉽게 접근할 수 있는 방식을 만드는 것이었습니다.
이를 위해 그는 하이퍼텍스트(HTML)와 인터넷(HTTP) 프로토콜을 기반으로 한 웹 브라우저와 웹 서버 개념을 개발했습니다. 이로 인해 사용자들이 인터넷을 통해 문서에 연결되고, 문서들 간에 쉽게 이동할 수 있게 되었습니다.
정보 공유와 접근성 향상이 초기 웹의 주요 역할이었습니다. 구체적으로 보면 다음과 같습니다.
정보의 연결성 (Hyperlink): 초기 웹의 핵심 개념은 하이퍼링크를 통해 문서들이 서로 연결된다는 것이었습니다. 하이퍼링크를 클릭함으로써 사용자는 다른 문서로 이동할 수 있었고, 이로 인해 지식과 정보가 네트워크 형태로 얽혀 쉽게 접근 가능해졌습니다. 이는 웹의 가장 혁신적인 개념 중 하나로, 이전의 단방향적 정보 제공 방식과는 달리 사용자가 정보를 유동적으로 탐색할 수 있는 길을 열었습니다.
비구조화된 데이터를 구조화된 형태로 제공: 웹은 비구조화된 텍스트 파일이나 이미지 데이터를 HTML 형식으로 구조화하여 제공함으로써, 문서 간의 일관성과 접근성을 높였습니다. 이는 문서들을 쉽게 검색하고 탐색할 수 있도록 했습니다.
멀티미디어의 통합: 초기 웹은 텍스트뿐만 아니라 이미지, 링크 등 다양한 형태의 데이터를 통합하여 정보를 제공할 수 있었습니다. 이는 단순한 텍스트 기반 정보 제공에서 멀티미디어 정보를 담는 플랫폼으로 발전할 가능성을 열어줬습니다.
전 세계적 접근성: 웹은 지역에 구애받지 않고 전 세계적으로 접근이 가능하게 설계되었습니다. 이를 통해 전 세계 연구자들이 같은 플랫폼에서 정보를 공유하고 협력할 수 있었습니다.
이러한 초기 웹을 통해 규격화된 정보 공유가 쉬워졌습니다.
초기 웹은 HTML, HTTP, URL로 비교적 간단하게 구성되어 있었습니다.
HTML (HyperText Markup Language)은 웹 문서를 작성하기 위한 언어로, 하이퍼텍스트와 링크를 통해 문서 간 연결을 가능하게 했습니다. HTML을 통해 텍스트에 구조를 부여할 수 있게 되었고 이미지나 링크 같은 다양한 요소들도 포함할 수 있었습니다.
HTTP (HyperText Transfer Protocol)는 클라이언트(웹 브라우저)와 서버 간의 통신을 담당하는 프로토콜로, 웹 페이지를 요청하고 받는 과정을 표준화했습니다.
URL (Uniform Resource Locator)은 웹 상의 각 문서나 자원에 대한 고유 주소 체계로, 이를 통해 사용자가 웹 페이지에 쉽게 접근할 수 있게 했습니다.
그러나 초기 웹의 경우 정적 콘텐츠만 제공 가능했고 실시간 상호작용이나 동적 콘텐츠 제공은 어려웠습니다. 또한 서로 다른 브라우저 간에 브라우저간에 호완성 문제가 있었습니다.이는 웹이 다양한 용도로 확장되고 더 복잡한 애플리케이션을 요구하면서 점점 더 큰 문제로 대두되었습니다. 특히, 기업들은 웹을 이용해 실시간 정보 제공, 사용자 입력 처리, 데이터베이스 연동 등의 기능을 원했고, 이를 위해 정적인 페이지를 넘어서 동적인 웹 페이지 생성이 필요했습니다.
이런 상황에서 1993년, NCSA(National Center for Supercomputing Applications)에서 Rob McCool이 웹 서버에서 외부 프로그램을 실행할 수 있도록 하기 위해 CGI(Common Gateway Interface)를 개발했습니다. 이는 웹 서버가 클라이언트 요청에 따라 외부 프로그램을 호출하고, 그 프로그램의 실행 결과를 사용자에게 전달하는 방식이었습니다.
CGI는 웹 서버와 외부 애플리케이션 간에 공통 인터페이스를 제공함으로써, 다양한 프로그래밍 언어로 작성된 프로그램(예: Perl, Python, C 등)이 웹 서버를 통해 실행될 수 있게 했습니다.
CGI 프로그램은 사용자가 제출한 데이터를 받아 처리한 후, 그 결과를 웹 서버로 전달하고, 웹 서버는 이를 HTML 형태로 변환하여 사용자에게 응답했습니다. 이를 통해 동적인 웹 페이지 생성이 가능해졌습니다.
CGI는 서버(Server)와 애플리케이션(application) 간에 데이터를 주고 받는 방식 또는 컨벤션을 뜻합니다. Interface 라는 이름에서 알 수 있듯, "웹서버"와 "요청을 받아 처리해줄 로직을 담고 있는 애플리케이션 프로그램" 사이의 인터페이스입니다. 웹서버가 특정 언어로 쓰인 구체적인 프로그램이 아니라 이 인터페이스에 의존하고 있기 때문에 어떤 언어든 이 인터페이스를 구현하기만 한다면(CGI 스펙을 따른다면) 웹서버와 소통할 수 있습니다.
CGI의 경우 웹 폼(form)에서 사용자가 입력한 데이터를 CGI 프로그램을 통해 처리하고, 그 결과를 사용자에게 제공합니다. 또한, CGI는 서버 측에서 데이터베이스와 상호작용할 수 있도록 하여, 실시간 데이터를 제공하는 웹 애플리케이션 개발을 가능하게 했습니다. 이를 통해 CGI 프로그램은 사용자의 요청에 따라 실시간으로 HTML 페이지를 생성할 수 있었습니다.
작동순서 : 사용자 요청 -> 웹 서버 요청 전달 -> CGI 프로그램 실행 -> 결과 반환
우선, 사용자가 웹 브라우저에서 특정 URL을 요청하거나, 폼에 데이터를 입력한 후 제출 버튼을 누릅니다.그러면 웹 서버는 해당 요청이 CGI 프로그램과 연관된 것인지 확인합니다. 이때, CGI 스크립트나 프로그램이 연관되어 있으면, 서버는 CGI 프로그램을 실행합니다.
여기서 CGI 프로그램은 사용자가 입력한 데이터를 처리하거나, 요청에 따라 데이터베이스에서 정보를 가져옵니다. 이 후 CGI 프로그램은 처리 결과를 HTML 형식으로 반환하며, 웹 서버는 그 결과를 사용자에게 전달합니다.
이러한 문제들이 있었기에 후에 FastCGI나 다른 서버 측 기술로 해결하려는 시도가 이루어지게 되었습니다. 그리고 이러한 CGI의 단점을 보완하고 같은 역할을 하는 기능이 자바로 만들어진게 바로 서블릿(Servlet)입니다.
서블릿(Servlet)은 자바(Java)로 작성된 서버 측 프로그램으로, 웹 요청을 처리하고 동적인 웹 페이지를 생성하는 데 사용됩니다. 서블릿은 Java EE(Enterprise Edition) 플랫폼의 일부로, 웹 서버와 클라이언트(웹 브라우저) 간의 상호작용을 처리하는 데 중요한 역할을 합니다.
서블릿은 동적인 웹 애플리케이션을 개발하기 위한 기술로, 클라이언트의 요청을 처리하고 그 결과를 HTML, JSON 등 다양한 형식으로 응답하는 Servlet 클래스의 구현 규칙을 지킨 자바(Java) 프로그래밍 기술입니다. 서블릿은 CGI(Common Gateway Interface)의 성능 문제를 해결하기 위해 등장했으며, 자바의 강력한 기능을 이용해 더 효율적이고 확장 가능한 웹 애플리케이션을 개발할 수 있게 해줍니다.
서블릿은 웹 컨테이너(또는 서블릿 컨테이너)라는 환경에서 실행됩니다. 이 웹 컨테이너는 서블릿의 생명 주기(lifecycle)를 관리하며, 클라이언트 요청이 들어올 때 서블릿이 요청을 처리할 수 있도록 합니다.
동작 순서 : 클라이언트 요청 -> 서블릿 호출 -> 요청 처리 -> 응답 반환 -> 서블릿 종료
클라이언트가 웹 브라우저에서 서버에 HTTP 요청을 보냅니다. 이 요청은 웹 서버를 통해 서블릿 컨테이너로 전달됩니다.
서블릿 컨테이너는 HTTP Request를 받으면 HttpServletRequest, HttpServletResponse 객체를 생성합니다.
웹 컨테이너는 요청 URL을 분석해서 web.xml을 보고 어느 서블릿(Servlet)에 대한 요청인지 찾습니다.
해당하는 서블릿에 요청을 전달합니다.
서블릿(Servlet)에서 service() 메소드를 호출합니다.
클라이언트의 POST, GET 요청 여부에 따라 doGet() 또는 doPost()를 호출합니다.
doGet(), doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse 객체로 응답을 보낸다.
Client에 HTTP Reponse로 응답을 보내고 끝나면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킨다.
// 서블릿이 처음 적재될 때 호출되는 초기화 함수, 서버가 켜질때 한번만 실행됩니다.
// 초기화 작업이나 자원 설정이 이 단계에서 이루어집니다.
public void init() {...}
// 클라이언트의 요청이 들어올 때마다 호출(doGet(), doPost())한다.
public void service() {...}
// 서블릿이 메모리에서 해제될 때 호출되는 종료 함수, 서버가 꺼질때 한번만 실행된다.
public void destroy() {...}
서블릿은 웹 애플리케이션의 기본 기술로 널리 사용되었지만, 그 이후 더 발전된 프레임워크들이 등장하면서 서블릿은 프레임워크의 기반 기술로 주로 사용되었습니다. 대표적인 예가 바로 Spring MVC입니다. Spring MVC의 경우 서블릿 기반으로 만들어진 프레임워크로, 서블릿의 복잡한 부분을 감추고 더 효율적으로 웹 애플리케이션을 개발할 수 있게 해주었습니다.
CGI와 서블릿 두 기술 모두 웹 서버에서 동적인 웹 페이지를 생성하고 클라이언트에게 응답하기 위해 사용됩니다. 거기다 클라이언트가 보낸 HTTP 요청을 서버가 처리하고 클라이언트에게 HTML, JSON등 다양한 형식으로 응답을 돌려줍니다.이러한 공통점이 있기에 상당히 헷갈릴 수 있기에 둘의 차이를 표로 정리해보았습니다.
특징 | CGI | 서블릿 |
---|---|---|
언어 | 여러 언어(Python, Perl, C 등) 사용 가능 | 자바(Java) 기반 |
요청 처리 방식 | 각 요청마다 새로운 프로세스 생성 | 요청마다 스레드 생성(프로세스 생성 없음) |
성능 | 프로세스 생성 오버헤드로 성능 저하 가능 | 스레드 기반으로 성능 우수 |
상태 관리 | 무상태(stateless), 별도 관리 필요 | 세션/쿠키 등을 사용해 상태 관리 가능 |
확장성 | 확장성이 낮고, 대규모 트래픽 처리에 부적합 | 확장성 높고, 대규모 웹 애플리케이션에 적합 |
플랫폼 의존성 | 플랫폼 독립적 | 자바 환경에서 실행 |
서블릿은 자바 기반의 동적 웹 애플리케이션을 개발하는 핵심 기술로, 웹 서버와 클라이언트 간의 요청-응답을 처리하는 중요한 역할을 합니다. 서블릿은 성능이 뛰어나고 확장 가능하며, 자바의 안정성과 플랫폼 독립성을 이용해 다양한 웹 애플리케이션에서 널리 사용되었습니다. 때문에 이를 기반으로 한 Spring 플랫폼이 나올 수 있었습니다. 다음시간에는 Spring에 대한 얘기를 해보겠습니다.