Spring (5)
0. 지극히 개인적인 정리
1. Web Server
1) HTTP 기반으로 동작
2) 정적 리소스(HTML, CSS, JS, 이미지, 영상 등) 및 부가 기능을 제공
예) Nginx, Apache
2. Web Application Server
1) HTTP 기반으로 동작
2) Web Server 기능 + Application logic 수행 -> Application code 실행에 특화
3) 동적 HTML, HTML API 생성, Servlet, JSP, Spring MVC 동작
4) 문제
(1) WAS가 너무 많은 역할을 담당하여 서버 과부하 우려
(2) 비싼 애플리케이션 로직이 정적 리소스때문에 수행이 어려운 경우가 존재
(3) WAS에서 장애가 발생하면 오류시 출력되는 화면도 표시가 불가능
3. Servlet
1) Java(혹은 다른 언어)를 사용하여 웹 페이지를 동적으로 생성하는 server side program 혹은 spec
2) @WebServlet parameter로 urlPatterns에 값을 담아서 Servlet 코드를 실행
// servlet 이름과 url mapping 명은 겹치면 안됨
@WebServlet(name="helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
// servlet 호출 시 service method 호출
@Override
protected void service(HttpServletRequest request
, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet.service");
System.out.println("request = " + request);
System.out.println("response = " + response);
String username = request.getParameter("username");
System.out.println("username = "+username);
/**
* header정보에 들어감
*/
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().write("hello! "+username);
}
}
2) HTTP message를 일일이 parsing하는 건 힘듦 -> Servlet에서 request, response 객체를 사용하면 쉬워짐
3) 흐름
(1) HTTP request
(2) WAS에서 request, response 객체를 만들어서 Servlet 객체 호출
(3) request, response 객체에서 HTTP request, HTTP response 정보 꺼내서 사용 가능
4) Servlet container
(1) WAS 내에 있는 Servlet container에서 객체를 생성, 초기화, 호출, 종료 가능 -> 생명주기 관리
(2) Servlet 객체는 Singleton으로 관리
- request, response 객체는 요청이 올 때마다 새로 생성됨
- 하지만, Servlet에 요청이 올 때마다 Servlet 객체를 만들면 비효율적이므로 객체를 재사용
- 최초 로딩시점에 Servlet 객체를 미리 만들어서 해당 객체를 사용
- 따라서, 공유 변수를 사용할 때 조심해야함
(3) JSP도 Servlet으로 변환되어 사용
(4) 동시 요청을 위한 multi thread 처리를 지원함
4. multi thread
1) thread: 애플리케이션 코드를 하나하나 순차적으로 실행
(1) Java main method를 처음 실행하면 main이라는 이름의 thread가 실행됨
(2) thread가 없으면 Java Application 실행이 불가능
(3) thread는 한 번에 하나의 코드 라인만 실행함
(4) 동시 처리가 필요하면 thread를 추가로 생성해야 함
2) 다중 요청 시 thread 사용
(1) 요청 A를 처리하던 중 지연이 발생 -> 요청 B가 발생 -> 둘 다 timeout 문제 발생
(2) 신규 thread를 하나 생성하면 요청 A는 처리중이라도 요청 B를 신규 thread에서 처리할 수 있음
(3) 따라서, 요청이 생기면 그때마다 thread를 만들자
- 리소스 허용 범위 안에서 모든 요청 처리 가능
- 동시 요청 처리 가능
- 어느 하나의 thread에서 지연이 발생돼도 다른 thread가 동작
(4) thread를 마구 만들면 문제가 있다
- thread의 생성 비용은 비싼데?
- context switching pay 발생: CPU 코어 하나가 병렬 실행하면서 thread 전환 시 비용이 발생
- thread 생성에 제한이 없는 것도 문제: 요청이 너무 많아져서 thread가 너무 늘어나면 CPU, 메모리 사망
3) thread pool
(1) 필요한 thread를 pool에 보관하고 관리
(2) 정해놓은 양의 thread를 pool안에 생성해놨다가 필요할 때 꺼내 쓰고 다 쓰면 pool에 반납
(3) pool에 있는 thread 보다 더 많은 요청이 들어오면 대기 혹은 거절
(4) Tomcat은 200개가 기본 설정
(5) thread가 미리 생성되어 있으므로 생성 및 종료 비용 절감 가능
(6) 응답시간이 빠름
(7) 생성 가능한 thread 최대치가 있으므로 너무 많은 요청이 들어와도 기존의 요청은 안전하게 처리 가능
※ point!
(1) WAS 주요 튜닝 포인트는 최대 thread 숫자
- thread 숫자를 낮게 설정해놓으면 server 리소스는 여유가 있지만, client는 금세 응답 지연을 맞이함
- thread 숫자를 너무 높게 설정하면 CPU, 메모리 리소스 임계점 초과로 server down 발생
(2) 장애 발생 시 클라우드 서버일 경우는 서버를 늘리고 튜닝
- 클라우드 서버가 아니면 우선적으로 튜닝
(3) thread 적정 숫자 찾기 -> 상황에 따라 다 다름
- 애플리케이션 로직 복잡도, CPU, 메모리, IO 리소스 상황을 다 고려해야하므로
- 성능 테스트를 통해 적정값을 찾는 수밖에 없음
- Apache ab, 제이미터, ngrinder 등으로 테스트
5. Server Side Rendering
1) server에서 최종적으로 HTML을 생성하여 client에게 전달
2) server에서 동적으로 HTML을 생성
3) JSP, thymeleaf
6. Client Side Rendering
1) HTML 결과를 JS를 이용하여 웹 브라우저에 동적으로 생성하여 사용
2) 주로 동적인 화면에서 사용
3) 웹 환경을 앱처럼 필요한 부분만 변경할 수 있음
4) React, Vue
※ 서버 사이드 렌더링과 클라이언트 사이드 렌더링은 장,단점이 있어서 양쪽 기술을 섞어서 사용하는 경우도 많음
7. Java backend web 기술 개요
1) 1997년 Servlet 등장
(1) HTML 동적 생성이 어려움
2) 1999년 JSP 등장
(1) Java Server Page: 화면 + 비즈니스 로직 -> 너무 많은 역할을 담당
3) Servlet, JSP를 조합하여 MVC 패턴을 사용
(1) Struts, 웹 워크, Spring MVC 등 춘추전국시대
(2) Annotation 기반의 Spring MVC 등장
(3) Spring boot가 등장하면서 불편했던 설정문제 해결과 함께 다양한 기능을 묶어서 제공
- 서버를 내장하여 WAS를 별도로 직접 설치할 필요가 없어짐: 빌드할 때 Tomcat 서버를 넣어버림
4) 이후 분류
(1) Servlet 기반의 Spring MVC
(2) Web reactive stack의 Spring WebFlux
※ Spring WebFlux
(1) 비동기 넌 블러킹 처리
(2) 최소 thread로 최대 성능 구현: thread context switch pay 효율화
(3) 함수형 스타일로 개발
(4) Servlet 기술 사용 안함
(5) 고난도의 기술
(6) RDB 지원 안 함: Redis, ElasticSearch, MongoDB 등에 적합
(7) 현 일반 MVC thread 모델도 충분히 빠름
5) template
(1) JSP: 느리고 기능이 부족함
(2) 프리마커, velocity: JSP의 느린 속도 개선
(3) thymeleaf: Spring MVC와 기능적으로 통합, Spring에서 표준으로 밀어줌
- HTML 모양 유지하면서 view template 적용 가능