인프런 김영한 님의 스프링 MVC 1편 - 웹 개발 핵심 기술 을 수강하고 정리한 내용입니다. 김영한님 체고.
스프링은 공부해도 공부해도 정말정말 공부할게 너무 많다. 근데 마침 김영한 님께서 MVC 강의를 다시 내주셨다니! 복습할 겸 다시 들어보려고 한다.
김영한님 강의 답게 빌드업이 조지게 좋은 만큼 서블릿부터 다시한번 해보신다고 하니까 다시 해봐야겠다.
섹션 1에서는 그냥 전반적인 클라이언트 서버 구조, 간단한 네트워크, 간단한 http 등을 슥 보고 간다. 재밌당.
웹은 기반으로 http 기반으로 통신을 합니다.
클라이언트에서 서버로 요청을 할 때, 서버에서 클라이언트로 응답할 때, http 기반으로 이루어집니다.
지금은 http의 시대!
-WAS, DB만으로 시스템 구성이 가능함.
-WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능.
-WAS가 너무 많은 일을 담당하는데..? 앱 로직도 실행하고, 정적 컨텐츠도 계속 제공하고…. 정작 중요한 어플리케이션 로직, 그러니까 “비싼” 로직이 이미지 이런 정적 리소스 때문에 수행이 어려워지면 안되잖아…
만약 WAS가 죽는다면? 우리가 로직을 잘못 짠다거나, 디비가 오류가 난다거나… 한다면 심지어 오류 화면 조차 노출 불가능함.
그래서, 일반적으로는
client -> web server(정적 리소스를 여기서 처리) -> WAS에서 로직 처리 -> 디비
이런 식으로 처리를 함. 시스템 리소스를 효율적으로 처리할 수가 있음. 만약 앱 리소스가 더 많이 처리한다? 그러면 WAS만 늘리면 됨.
또한, 정적 리소스 서버 그러니까 웹 서버는 잘 죽지도 않습니다. 그래서 WAS가 죽더라도, 정적 리소스 서버에서 오류화면을 띄울 수가 있습니다. + 요새는 CDN을 따로 둬서 정적 리소스 서버를 늘리기도?
만약 api만 제공한다면 was만 구축하기도 합니다.
만약 폼 인증을 직접 구현한다면?
일단 폼 인증을 한다면 http 메시지가 생성이 되어서 날아가겠죠?
그러면
거기다가 만약 udp라면..? 끔찍하네요…
사실 중요한건 비즈니스 로직을 실행하는겁니다! 즉, 서블릿이 비즈니스 로직을 제외한 모든 기능들을 WAS에서 다 지원해줍니다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServelt {
@Override void service(HttpServletRequest request, HttpServletResponse respnse) {
//애플리케이션 로직
}
}
-어노테이션 안의 url로 들어왔을 때 처리!
-service 안의 로직만 구현하면 됨.
-request, response를 직접 파싱하고 정리하고 만들려면 이게 굉장히 귀찮겠죠? 그냥 request, response 객체를 가져다 쓰면 됩니다! request.getUsername()이런 것 처럼
-응답 정보도 response에다가 내가 원하는거 그냥 잘 넣으면 됩니다!
하지만 http 스펙은 기본적으로 알고 있어야 합니다!
http 요청시
-was는 request, response 객체를 새로 만들어서 서블릿 객체 호출
-개발자는 request 객체에서 http 요청 정보를 편리하게 꺼내서 사용!
-개발자는 response 객체에 http 응답 정보를 편리하게 입력!
-was는 response 객체에 담겨있는 내용으로 http 응답 정보를 생성! 그러면 웹서버가 html 이쁘게 렌더링 해서 보내줍니다.
서블릿을 지원하는 was 안에는 서블릿 컨테이너가 있는데, 이 서블릿 컨테이너에서 서블릿을 관리해줍니다.
그래 알겠어. 요청이 올때마다 was의 서블릿 컨테이너에서 서블릿을 꺼내서 쓰는구나.
근데 서블릿은 누가 호출하지..? 바로 쓰레드가 호출합니다.
-애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드!
-자바의 메인 메서드를 실행하면 main이라는 이름의 쓰레드가 실행됩니다.
-만약 동시 처리가 필요하다면 쓰레드를 생성해야 합니다!
장점
-동시 요청을 처리할 수 있음
-리소스가 허용할 때 까지 처리 가능
-하나의 쓰레드가 지연되어도 나머지는 정상작동
단점
쓰레드는 생성 비용이 매우 비싸다! -> 고객의 요청이 올 때마다 스레드를 생성하면 응답 속도가 늦어진다.
쓰레드는 컨텍스트 스위칭 비용이 발생한다! 운영체제에서 컨텍스트 스위칭..하는데…운체 강의 들어야 되는데… 과제도 해야되는데… 큰일..났네요..
쓰레드 생성에 제한이 없다. like 치킨 디도스 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ : 고객 요청이 너무 많으면 만개의 쓰레드를 만들면 cpu 메모리 임계점을 넘어버려서 서버가 죽어버릴 수도 ㅋㅋㅋㅋㅋ
=> 그래서 어떻게 하냐? 대부분의 was에서는 쓰레드 풀을 만들어 놓습니다. 가령, 쓰레드 풀을 200개 만들어 놓고 있으면, 하나씩 쓰는 겁니다.
=> 그러고 쓰레드를 다 쓰면 죽이는게 아니라, 이걸 다시 반납을 해줍니다.
=> 만약 쓰레드 풀의 갯수를 넘는다면, 우리 다 찼어 못해줘! 하고 뱉어버리거나, like 맛집 대기열처럼 대기열을 받아줌. 저희는 10명까지만 받을게요!
필요한 쓰레드를 쓰레드 풀에 보관하고 관리
쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리. 톰캣은 최대 200개 기본 설정.
요청이 오면 이미 만들어진 쓰레드를 풀에서 꺼내서 사용한다.
끝나면 반납한다.
다 쓰고 있으면 거절하거나 대기하도록 설정한다.
장점
실무 팁
was의 주요 튜닝 포인트는 최대 쓰레드 수(max thread)이다. 요 값을 튜닝했을 때 가장 효과가 좋습니다.
이 값이 너무 낮으면? 우리 서버는 사양이 낮아..그러니까 그냥 안전하게 하자… 근데 서비스가 대박이 나서 막 요청이 100개가 들어와.
-> 그러면 10개만 돌고 90개는 기다리겠지? 그럼 막 으악 고객 요청 겁나 많이 들어와 어떻게?
-> 개발자니까 이제 가서 cpu 사용량을 봅니다. 음..5% 사용중이군…ㅋㅋ아주 치욕적이네요..못해도 50%는 써야되는데!!!! 근데 이걸로 막 aws 인스턴스 10개로 늘리고…. 돈 10배로 나가고…
그럼 높게 가자. 한 만개 쓰자.
-> cpu, 메모리 리소스 임계점 초과
-> 서버 다운 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
장애 발생시?
-장애가 났으면 일단 처리해야지. 급하니까. 클라우드면 늘리고 나중에 튜닝합시다.
-아니면 평소에 튜닝 잘하세요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
적정 숫자는 어떻게 찾나요?
-그냥 100개 쓰세요 200개 쓰세요 하는건 잘못된 겁니다! 어플리케이션 로직의 복잡도, cpu 메모리, io 리소스 상황에 따라 모두 다릅니다!
-성능 테스트를 결국 해봐야 합니다.
: 최대한 실제 서비스와 유사하게 성능 테스트 시도, nGrinder 추천. 스크립트 짜서 쭉 요청 해보기! 만약 못받으면 병목 포인트 찾아서 튜닝!
-WAS가 멀티 쓰레드를 해줍니다. 이거 직접 짜면 머리 터져요.
-개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않으면 됩니다. 비즈니스 로직만 처리하면 됩니다! 설정만 해주면 댑니다!
-개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발, WAS의 가아아아아자아아앙앙 큰 장점
-멀티 쓰레드 환경이기 때문에 싱글톤 객체(서블릿, 스프링 빈)은 주의해서 사용할 것!
요새는 다들 리엑트, vue 같은것들 쓰니까 api 넘겨주면 되는 것 같습니당. 또 micro service 후.. 에서 많이 쓰죠.
백엔드에서 고민할 것은 세가지! 정적 리소스 어떻게 제공할거야, 동적 Html 어떻게 제공할거야, api 어떻게 줄거야?
사실 세상이 막 딱딱 나눠지진 않죠. 서로 동시에 지원하는 프레임 워크도 있고 막 그렇습니다.
나는 아무래도 막 클라이언트 프론트 쪽 보다는 백이 좋더라… 예전 프로젝트에서 급하게 프론트 하던 일이 있었는데.. ~다 때려 부수고 싶더라...~
그래도 요새는 리엑트 공부해보고 싶다!
고대에 서블릿이란게 있었습니다.
1. 서블릿
고대에 서블릿이 있었는데 자바 코드로 html을 만들기가 어려웠죠. 그래서 jsp가 나옵니다.
2. jsp : html은 편리하기는 한데 비즈니스 로직이 너무 많아서 막 한 파일에 와장창
3. 서블릿, jsp 조합 mvc 패턴 사용 : 관심사를 나누는 거죠.
4. mvc 프레임워크 춘추 전국 시대 : 2000 ~ 2010년 초. 아 이거 비슷하니까 나도 프레임워크 만들어봐야징. 스트럿츠, 앱워크 , 등등. mvc 패턴 자동화, 웹 기술 편리하게 사용하는 등의 다양한 기능 지원.
5. 애노테이션 기반의 스프링 mvc 등장! : @Controller. 얘는 모든 장단점을 다 해결해버렸어요. 원래 스프링 + 다른 MVC 프레임워크 이렇게 썼었는데. 안그래도 스프링 코어는 많이 썼었는데 MVC를 준다? 바로 뚝딱. 거기다가 애노테이션으로 깔끔. 그냥 통일.
6. 스프링 부트의 등장
- 결국 개발자들이 불편해 했던 것들을 다 자동화해줌.
- 스프링 부트는 서버를 내장!
- 과거에는 was(톰캣 등)를 서버에다 설치하고 실행. 그리고 소스코드는 소스코드대로 따로 만들어서 빌드. jar 모아서 war로. 그리고 이걸 배포 폴더에다가 넣어가지고 막 아주 그냥 소스 빌드하고 아주 복잡하고 번거로웠는데
- 스프링 부트가 그냥 빌드할 때 톰캣 서버를 넣어버림. 이러면 서버에 톰캣, was를 할 필요가 없음. 걍 jar를 실행해 버리면 그냥 한방에 실행.
WebFlux?
특징
그런데
요번에 프로젝트가 MSA로 진행하면서 Web Flux를 쓸까 할 때 RDB 쓰지 말라 했던게
그래서구낭..