본문 바로가기

Spring

Spring 이론 - 클라이언트와 서버 Tomcat / Servlet / JSP

spring 이론을 처음 공부했을 때 너무 대충 공부했던 거 같다. 다시 차근차근 기초부터 다져보자. 

 

제 목표는 진짜 저같은 바보도 이해하기 쉽게 작성하는게 목표에요.. 까먹었을 때 또 봐야하잖아요?ㅠ

 

Client - 서비스를 요청하는 애플리케이션 (내 정보 보여줘)

Server - 서비스를 제공하는 애플리케이션 (니 정보 어딨더라.. 찾아볼게.. 예따 니 정보)

 

WebServer - 브라우저를 통해 받을 수 있는 모든 서비스 제공 (문서, 이미지, 동영상 다 볼 수 있잖아요?)

 

1. 서버의 port

 

혹시 url에서 https://000.000.0000:8080 보신 적 있나요? :8080이 포트 번호입니다. 

 

한 대의 pc(서버)에는 여러 서버 프로그램들이 존재할 수 있어요. 예를 들어 메일 서버와 파일 서버가 존재하는 것처럼요.

 

근데 IP만으로는 전송된 패킷이 어떤 응용 프로그램으로 보내야 할지 모른다는 거예요. 그래서 Ip 뒤에 어디로 갈지 상세 주소로 나타낸 것이 포트입니다!

 

예를 들어 80 포트는 HTTP 프로토콜이구나 하고 알 수 있는 거죠.

 

2. WAS(Wap Application Server)

 

말 그대로 웹 애플리케이션을 서비스하는 서버입니다. 무슨 말인지 모르겠죠? 나만 몰라?

 

Web Application 서비스 -> Application 서비스 -> Application = Program 

 

WAS는 서버에 프로그램을 설치하고 클라이언트가 이 프로그램을 사용할 수 있게 해주는 겁니다. 그럼 서버에 있는 프로그램만 고치면 클라이언트들은 업데이트된 Application을 이용할 수 있는 거예요!

 

여기서 톰캣 (Apache Tomcat)이 서버 프로그램입니다.

 

* Web Server와의 차이점을 알아야 하는데 웹 서버는 정적인 콘텐츠를 제공해 주는 서버이고, 동적인 콘텐츠를 제공하기 위해서 WAS를 이용합니다.

 

* 정적인 콘텐츠라 함은 클라이언트의 요청에 따라 변하지 않는, 미리 준비된 콘텐츠이며 동적인 콘텐츠는 클라이언트의 요청에 따라 생성되며 사용자 맞춤형 콘텐츠를 제공합니다. 서블릿/JSP/PHP 등 더 쉽게 이해하자면 사용자마다 내 정보가 다를 거 아니에요? 이게 동적 콘텐츠예요!

 

+ 사실 톰캣은 서블릿 컨테이너에 가깝다고 합니다. 자체 웹 서버가 내장 돼있기 때문에 WAS 기능을 일부 가지고 있는 서블릿 컨테이너라고 합니다.

 

3. Servlet 

 

다들 서블릿이 뭔지 아시나요..? 서블릿은 동적인 웹 페이지를 만들 때 사용되는 java 기반의 웹 애플리케이션 프로그래밍 기술입니다. 처음에는 정적인 요청에 대한 응답만 가능했는데 동적인 페이지를 만들고자 만든 프로그램이었죠

출처 - [Web] 서블릿(Servlet)이란 무엇인가? 서블릿 총정리 (tistory.com)

 

  • 서블릿은 자바 클래스입니다. 
  • 웹 서버에서 실행되며 HTTP 요청을 처리하고 응답을 생성하는 역할을 합니다. 

무슨 소린가 싶죠? 

@WebServlet("/hello")
public class HelloServlet extens HttpServlet{
   @Override
   public void init() throws ServletException{
      // 서블릿 초기화 - 생성될 때 한 번만 수행
   }
   
   @Override
   public void service(HttpServletRequest request, HttpServletResponse response){
      // 호출될 때마다 반복적으로 수행
   }
   
   @Override
   public void destroy() {
      // 서블릿이 제거될 때 한 번만 수행
   }
}

 

요청이 오면 요청과 매핑된 서블릿을 찾게 됩니다. 우리는 대충 어노테이션에 대해서 아니까 @WebServlet("/hello")가 매핑이 되어있구나라고 알 수 있죠? 이건 현대적인 방법이고, 예전에는 web.xml(서블릿 설정 파일)에 정의되었습니다. 어떻게? 

<web-app>
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

 

이렇게 말이죠. 어차피 요즘은 간단하게 어노테이션 써서 이거까지 알아야 되나 싶긴 한데 저도 공부하는 중이고, 미리 말하자면 스프링은 서블릿 바탕이니까 언젠간 도움이 되지 않을까요? 

 

서블릿 인스턴스가 존재하는지 Servelt Context에서 확인하고 없으면 init()을 통해 생성하고 있으면 service()를 호출합니다. 

 

여기서 알아야 할 점. 서블릿은 싱글톤 패턴으로 인스턴스를 하나만 생성합니다. 어차피 요청에 대한 service() 로직은 똑같으니까요! 

 

여기서 싱글톤 패턴을 아시는 분이라면 그럼 어떻게 여러 명의 요청이 처리가 가능한 거지..? 해볼 만합니다. 

 

그건 서블릿 컨테이너가 멀티스레딩을 통해 각 요청을 독립적인 스레드에서 처리하기 때문입니다! (스레드도 정리해야겠네)

 

4. JSP

 

JSP도 서블릿과 똑같습니다. 하는 일은. 동적인 웹 페이지를 위한 것이죠. 근데 이제 차이는 있겠죠? 

 

구조를 알아두면 이해하는데 조금이라도 도움이 될 수 있겠죠..? 서블릿은 service() 메서드 안에 HTML 코드를 넣고 HTML 코드 중간에 동적인 코드를 추가하는 방식입니다. 이건.. 상상만 해도 복잡하지 않나요? 

 

그래서 나온 게 HTML 코드에 자바 코드를 끼워 넣는 방식으로 동적인 웹 페이지를 제공할 수 있습니다.

<%@ page import="java.util.List" %>
<%@ page import="com.example.model.User" %>
<%@ page import="com.example.service.UserService" %>
<%
    UserService userService = new UserService();
    List<User> users = userService.getAllUsers();
%>
<html>
<head>
    <title>User List</title>
</head>
<body>
    <h1>Users</h1>
    <ul>
        <%
            for (User user : users) {
                out.println("<li>" + user.getName() + "</li>");
            }
        %>
    </ul>
</body>
</html>

 

역시나 예시 보면 바로 이해가 됩니다. 이해 하나도 안 되는데요? 괜찮아요. 우리가 볼 건 JSP로 해도 서블릿 보단 편해졌지만 여전히 복잡하다는 겁니다. 상단부에 java 코드로 비즈니스 로직 들어가 있는 거 보이죠? 코드가 전부 노출되어 있어서 이것도 쉽지 않은 방법이죠.. 

 

다들.. spring MVC 아세요? 그래서 나온 게 springMVC입니다!!!!!!! MVC 패턴이 쉽게 말해서 로직을 분리한 거라고 하잖아요? 하나의 서블릿이나 JSP가 처리하던걸 MVC 영역으로 나눈 패턴이에요. 그래서 나왔어요. 이렇게 탄생? 과정을 이해하니까 너무 이해가 잘되네요..  (JSP 문법은 따로 정리하겠습니다.)

 

* 다시 MVC 간단하게 설명하면 요청을 받은 컨트롤러가 비즈니스 로직을 실행하고 결과를 모델에 담아서 뷰로 보내면 뷰가 모델에 담겨있는 데이터를 가지고 화면을 출력합니다. 모델은 데이터를 담아두는 저장 공간이 되겠네요!

 

* 서비스와 리포지토리 계층이 컨트롤러에서 또 분리가 되어 있는데 유지 보수가 용이하다는 장점이 있습니다. 

 

5. Tomcat 구조

 

톰캣 얘기하려고 했는데 돌고 돌아서 이제야 왔네요. 저도 프로젝트를 하면서 서버로 톰캣을 썼는데요. 사실 잘 모르고 썼다는 게 맞겠죠. 개념이라도 제대로 알아봅시다!

 

다시 말하자면 톰캣은 서블릿 컨테이너라고 했잖아요? 

  • 서블릿 생명주기 관리 (init, service, destory)
  • HTTP 요청 및 응답 처리 (들어온 요청을 적절한 서블릿으로 전달 후 반환한 응답을 클라이언트에게 반환)
  • 멀티스레딩 지원 (동시에 다수 요청 처리)
  • JSP 지원 (JSP 파일을 서블릿으로 변환 후 실행 (처음만))
  • 웹 애플리케이션 배포

아까 알아봤던 서블릿으로 인해 대부분은 이해가 가네요. 그렇지 않나요? 

 

내부 구조에 대해서 알아볼까요? 

제가 들었던 강의인데 문제되면 지우겠습니다.

 

1. 클라이언트의 요청이 들어오면 요청의 프로토콜에 따라 적절한 Connector가 달라진다. 

<Connector port="8080" protocol="HTTP/1.1" 
           connectionTimeout="20000" // 클라이언트가 요청을 보내는 동안 기다릴 시간
           redirectPort="8443" // 보안(HTTPS) 연결 리다이렉션
           maxParameterCount="1000" /> // URL과 POST 데이터에서 허용할 최대 매개 변수

 

톰캣 설정 파일은 server.xml을 통해 확인할 수 있는데 이렇게 Connector를 정의해놨을 거예요. 무슨 뜻이냐면 HTTP 요청을 8080 포트에서 수신하겠다! 이런 뜻이죠. 

 

connectionTimeout은 클라이언트가 20초 내에 요청을 완료하지 못하면 서버가 연결을 종료하겠다는 뜻인데요. 뭔가 알겠는데 모르겠지 않나요? 예를 들게요. 클라이언트가 아이디와 비밀번호를 입력하고 로그인 요청을 보냈어요. 근데 네트워크 연결이 불안정해져서 요청만 가고 요청 데이터(아이디, 비밀번호)는 서버에 도달하지 않은 거예요. 이때 서버는 20초만 기다리겠다. 이 말입니다.

 

2. 요청 처리 및 스레드 할당

 

Connector가 요청을 수신하면 Thread Pool에서 놀고 있는 스레드를 할당받습니다. 

 

스레드 풀이 뭐냐면 스레드들을 미리 만들어 두었다가 요청이 오면 하나의 스레드가 맡아서 요청을 처리하게 됩니다. 

 

server.xml을 뒤져보면 스레드에 관해 못 찾을 텐데요. Tomcat이 기본값을 사용해서 그렇습니다. 

  • maxThreads = 200 // 생성 가능한 최대 스레드 수 
  • minSpareThreads = 10 // 최소 유후 스레드 수
  • acceptCount = 100 // 요청 대기 수

아하 스레드들을 미리 만들어 둔다 했으니까 200개의 스레드를 만들어 두겠네요? 그럼 200개 이상의 요청이 들어오면 또 최대 100개의 요청 대기열이 있겠네요? 유후 스레드는 뭐지..? 유후 스레드는 놀고 있는 스레드입니다. 아무리 요청이 들어와도 놀고 있는 스레드 10개는 유지하겠다. 이 말이에요. 만약 대기열도 가득 차면 톰캣은 더 이상 요청을 받아들이지 않고, 클라이언트에게 연결 거부를 응답합니다. 사람이 많이 몰리면 연결이 안되는 이유일까요? ㅎㅅㅎ

 

3. 요청 파싱 및 매핑

 

할당된 스레드는 HttpServletRequest와 HttpServletResponse 객체를 생성하여 요청 및 응답을 처리합니다. 

 

톰캣은 요청을 URI를 기반으로 Engine, Host, Context로 요청을 전달할지 결정합니다.

<Engine name="Catalina" defaultHost="localhost">
    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Context path="" docBase="myapp" />
    </Host>
</Engine>

 

server.xml에 보면 이런 구조로 되어 있어요~ 톰캣의 경우 엔진 이름이 Catalina네요. 아마 다 다른가 봅니다..? 

 

자 우리는 하나하나 다 알아야 이해가 가능하죠? 일단 위~~에 그림 보면 하나의 서비스 안에 하나의 엔진 안에 여러개의 호스트와 컨텍스트가 존재합니다. 

 

Host는 example.com이라는 도메인을 가진 시장이라고 합시다. 

그럼 시장에 신발 가게도 있을거고, 옷 가게도 있을거에요. example.com/shoes 와 example.com/clothes 이렇게 말이죠. 각각이 Context입니다. (근데 이게 URI 경로가 아니고 패키지라고 생각하셔야 합니다. )

각각의 Context에는 여러 구성 요소들이 존재할거에요. 이미지 파일, html, js, css 등등 이 각각의 Context별 설정 파일이 web.xml 입니다.

 

Context들을 웹 애플리케이션이라고 부르나봐요. ( 더 쉬운 이해 방법이 있다면 알려주세요 ㅜ)

 

4. 서블릿 매핑

 

Context 내에서 요청 URI를 기반으로 어떤 서블릿이 요청을 처리할 지 결정합니다. spring MVC에선 @Controller 어노테이션으로 컨트롤러 클래스를 정의하고 @GetMapping @PostMapping @RequestMapping을 이용해서 매핑하죠?

 

5. 서블릿 실행

 

톰캣이 서블릿 생명주기를 담당하잖아요? 서블릿이 처음 요청되면 init() 메서드를 호출하고, 요청에 따라 service() 메서드를 호출하여 Get과 Post에 따라 doGet(), doPost()등을 호출합니다. 당연히 종료될 떄 destory() 메서드 호출.

 

6. 응답 생성 및 반환

 

서블릿이 요청을 처리한 후, 결과를 HttpServletResponse 객체에 작성합니다. 그리고 응답을 클라이언트에게 반환하죠.

 

7. 쓰레드 반환

 

요청이 처리되면 쓰레드는 쓰레드 풀로 반환되어 다음 요청을 기다립니다.

 

어떻게 좀 이해가 되시나요? 

 

 


 

참고 출처

[Web] 서블릿(Servlet)이란 무엇인가? 서블릿 총정리 (tistory.com)

 

[Web] 서블릿(Servlet)이란 무엇인가? 서블릿 총정리

서블릿(Servlet)이란? 서블릿이란 Dynamic Web Page를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술입니다. 웹을 만들때는 다양한 요청(Request)과 응답(Response)이 있기 마련이고 이 요

coding-factory.tistory.com

 

'Spring' 카테고리의 다른 글

HTTP 특징  (0) 2024.06.13
spring MVC가 뭔데여(근데 이제 spring framework 특징을 곁들인)  (0) 2024.05.22
spring Annotation 모음  (0) 2024.05.22