Wanna be Brilliant Full-Stack Developer

Spring 서블릿 객체의 생명주기?? 본문

Some Memos/Spring 개념

Spring 서블릿 객체의 생명주기??

Flashpacker 2022. 2. 22. 13:22


서블릿 컨테이너라는게 무엇인가? 

클라이언트가 요청을하면 서블릿컨테이너 톰캣이 요청을 받고 요청을 받고나서 최초의 요청이면 객체를 생성하고 아니면 객체를 생성하지 않고 이미 생성된 객체를 재사용한다! 

우리가 요청하게 되면 요청을 받을떄 무조건 Spring에서도 동작하는것이 아니다. 

정적인파일을 요청하게되면 아파치가 돈다 ( HTML ,CSS, . PNG) 

이런 정적인 파일을 요청하게 되면 톰캣이 일을 안한다. 무조건 아파치가 일한다.

 

그러면 요청을 할떄 정적인 파일이 아니라 JAVA 파일을 요청하게 되면 톰캣이 일을 한다. 

그러면 SPRING할때 정적인 파일을 요청 하게되면 톰캣이 일을 안하겠네요? 물어보면 맞다 안한다.

하지만 SPRING은 정적인 파일을 요청할 수 없다.

왜냐하면 URL이라는것이 있고 URI가 있는데

URL은 자원에 접근할떄 사용하는 주소 요청방식이다. 여기서 L은 Location

URI의 I는 Identifier 식별자인데, 식별자를 통해서 접근하는 방식이다. 

 

그러면 요청시에 이런 파일들을 직접 요청하는 URL 접근 방식을 스프링은 다 막아놨다. 

그러면 식별자를 통해서 요청을 해야하는데 요청이 식별자를 통해 요청하니까 특정한 파일 요청을 할 수 없다. 

요청시에는 무조건 자바를 거친다!

이것은 무슨말이냐면 무조건 자바를 거치니까 무조건 아파치는 톰캣에게 제어권을 넘겨준다. 

왜냐하면 톰캣이 자바를 컴파일 할수 있으니까! 

 

URL은 보통 "http://naver.com/a.png 파일 이렇게 생겼다"

URI 는 "http://naver.com/Picture / a 형식으로 되어있는데 먼가 식별자의 느낌 파일이 아니다. 

어떤 식별자가 들어오면 실제로 는 a.png를 불러오겠지만 하지만 접근방식이 URL방식이 아니라 URI방식 식별자 접근으로 하게된다는것이다. 

이렇게 요청하게되면 자원에 요청하는것이 아니기 떄문에 URI방식은 톰캣이 다 가로채게 되어있다.


요청이 왔을때 서블릿 컨테이너가 객체를 생성하는 방식이 있는데 그거에 대한 이해를 해야한다! 

클라이언트가 리퀘스트 하게 되면 그떄 자바 관련된 어떤것들을 요청하게 되면 서블릿이 만들어져야한다?

이런 요청을 할떄는 톰캣이 서블릿 컨테이너.

서블릿이라는건 자바 코드로 웹을 할수 있는것을 말한다. 

이 서블릿 컨테이너라는건 자바코드로 웹을 할수 있는 것을 모아서 컨테이너로 만들어놨다는 것이다. 

 

그러면 요청을 했을떄 최초의 요청이 들어왔을떄 톰캣은 요청을 받을떄 스레드를 하나 만든다. 

해당 스레드가 서블릿 객체를 하나 만든다. 

서블랫 객체에서 수많은 일을 한다. ex) 데이터베이스 커넥션, 필요한 데이터 가져오고 등등 이러한 일들을 다하고 

나서 마지막에 HTML로 바꿔서 응답을 해주는데 

 

왜 스레드가 만들어지냐면 리퀘스트를 요청을 한명이 하는것이 아니라 동시에 수천명 수만명이 할수도 있다.

그러면 동시 처리를 위해서 요청이 올떄마다 스레드를 만든다. 

클라이언트 요청시마다 또한 새로운 스레드가 만들어진다. 

이렇게 만드는 이유는 서블릿 객체에서 만약에 데이터베이스 연결해서 어떤 데이터를 가져올떄 걸리는 시간이 만약 3초가 걸리면 새로운 스레드를 안만들게 되면 다른애들은 이 3초씩 기다려야하고 딜레이가 되기 때문에 

그래서 요청이 올떄마다 새로운 스레드가 동시접근을 허용하기 위해 생성된다..

 

하지만 이렇게 스레드가 무한정으로 만들어지는것이 아니라 만약 20개를 정해놓으면 내가 정해놓은 개수만큼만 만들어질수 있는데  20개수만큼 처리하고 있다가 21번쨰 요청이 들어오면 들어왔을때 아직 응답을 다 못해서 살아있는 상황이면 21번쨰 스레드를 만들지 못한다. 

그러면 21번쨰 요청은 대기! 그러면 스레드를 많이 만들어 놓으면 대기를 안하지 않냐? 

맞다! 하지만 그만큼 3초 걸릴일이 6초로 늘어나는등 느려질것이다.

그래서 최적의 스레드를 서버의 성능에 맞게 생성을 해야한다! 

 

지금은 20개를 가정했으니까 21번쨰 요청은 대기하고 있다가 첫번쨰 스레드가 응답을 하고 일을 다하면 

그러면 이 스레드의 역할은 끝난것이다. 왜냐하면 HTTP통신은 연결이 지속되어 있는것이 아니라 한번 요청하고 거기에대해 응답을 하면 끝나는거라고 했다. Stateless라고 했다.

 

그러면 응답을 했으니까 이 스레드는 사라져야 하지만 아니다. 사라지지 않고 재사용이 된다. 왜냐하면 21번쨰 요청이 들어왔으니까 이미있는것을 재사용한다. 그래서 속도가 빠르다고 하는것이다

왜냐하면 스레드를 계속 만들고 요청이 끝나면 삭제하고 다시 요청이 들어 올떄 다시 만들고 하면 만들고 날리고 하는 연산이 필요할텐데 

하지만 이렇게 어떤 적정의 개수를 정해 놓고 애들을 이렇게 지속적으로 사용하게되면 속도는 그만큼 빨라진다.

 

단순하게 말하자면 클라이언트가 요청을 하게 될떄 Spring같은 경우는 서블릿 컨테이너가 동작할수밖에 없는 구조이다. 왜냐하면 URI요청을 하기때문에

최초 요청을 하게되면 당연히 스레드에 아무것도 없으니까 메로리 로딩해서 서블릿 객체를 하나 만들고 실행을 한다! 

그리고 두번쨰 요청부터는 쭉 요청을 하면 최대 스레드 개수까지 요청이 쭉 될것이다. 

최대를 넘게되면 No가 요청이 될것이다 왜냐하면 기존에 있는것을 재사용할거기 떄문에!

 

나중에 최종적으로 만들어지는 것이 Request객체와 Response객체이다.

HTTPServletRequest 와 HTTPServletResponse이다. 이건 누가 가지고있냐면 스프링이 아니라 톰캣이 들고 있는 객체이다. 

 

어떻게하면 WEB이라는건 리퀘스트와 리스판스의 여행이다! 리퀘스트와 리스판스의 여행이 끝나면 WEB은 종료된다!