[Next.js] Next.js 14 Rendering 및 서버 실전 압축 정리
·
ETC
RenderingSSR(Server-Side Rendering): 매 요청마다 페이지를 서버에서 렌더링하여 클라이언트에 전송하는 방식특징요청 시마다 페이지가 서버에서 생성데이터를 동적으로 가져오기에 페이지는 최신 데이터를 반영유저별 동적 데이터 처리에 적합장점SEO에 유리최신 데이터 보장단점초기 로딩 시간 존재 -> Suspense를 사용하자많은 요청이 들어오면 서버 부하 발생적합한 사용처최신 데이터를 항상 보여줘야하는 페이지CSR(Client-Side Rendering): 브라우저가 초기 HTML, CSS, JavaScript 파일을 서버로부터 받아온 후, JavaScript를 통해 클라이언트(브라우저)에서 페이지를 렌더링하는 방식특징서버는 초기 HTML과 함께 JavaScript 파일을 제공하며, 이..
[MY-WAS] 나만의 WAS 만들기 프로젝트 (완) - HTTP 헤더 캐시
·
Project
이번 시간은 마지막으로 ETag 검증 헤더와 If-None-Match 조건부 요청을 사용하여 HTTP 헤더 캐시를 적용해보자. 관련된 내용은 '[Network]HTTP 헤더와 캐시'에서 다루었으니 참고하자.ETag & if-none-match검증 헤더 = ETag, 조건부 요청 = If-None-Match캐시용 데이터에 임의의 고유한 버전 이름을 달아두고, 데이터가 변경되면 이 이름을 변경함(Hash 다시 생성)단순히 ETag만 서버에 보내서 같으면 유지, 다르면 다시 받기서버에서 데이터가 변경될 때마다 ETag가 갱신되며, 이를 이용해 브라우저는 서버에 데이터가 변경되었는지 직접 확인웹 브라우저는 이전에 받아온 응답에 포함된 ETag 값을 If-None-Match 헤더로 사용하여 서버에 요청서버에서 데..
[MY-WAS] 나만의 WAS 만들기 프로젝트 (3) - Session & Cookie & JSON
·
Project
이번 시간에는 단순히 HTML만 내려주는 기능뿐이었던 프로젝트에 실제로 로그인 및 회원가입, 유저 정보 조회, 로그아웃 기능을 추가해보자. 이를 위해서는 WAS 서버에서 쿠키와 세션을 다룰 수 있어야 할 것이다. 더 나아가, HTML Form을 통한 통신뿐만 아니라 JSON을 통한 통신 방식도 지원하도록 개선해보자.역순으로 개발을 진행하면서 필요한 부분을 순차적으로 개발해나가자!UserController로그인 및 회원가입 기능, 유저 정보 조회 기능, 로그아웃 기능을 추가하자public class UserController { ... @RequestMapping("/login-action") public void loginAction(HttpRequest request, HttpRespo..
[MY-WAS] 나만의 WAS 만들기 프로젝트 (2) - 커맨드 패턴, 리플렉션, 애노테이션
·
Project
이전 시간에는 WAS의 아주 기본적인 기능들을 만들어보았다. 기능을 추가하기 전에, HttpRequestHandler의 다음 부분을 보자.private void process() { ... HttpResponse response = null; String requestURI = request.getRequestURI(); if (requestURI.equals("/login")) { response = new HttpResponse(HttpStatus.OK, requestURI, "/login.html"); } else if (requestURI.equals("/register")) { response = new HttpResponse(HttpStatu..
[MY-WAS] 나만의 WAS 만들기 프로젝트 (1) - 기본 구조
·
Project
이전 포스팅에서 자바에서의 소켓 통신을 다루었다. 이번에는 더 나아가서 직접 간단히 WAS를 구현해봄으로써 그 기능에 대해 확실히 이해해보자.WAS: 여러 web client의 요구를 web server가 감당할수없는 기능을 구조적으로 web server와 분리하기 위해 만들어진 것으로 Web Application Server(WAS) 라고 한다. web server가 요청을 받으면, WAS가 애플리케이션에 대한 로직을 실행하여 web server로 다시 반환해준다. 자세한 내용은 추후 포스팅에서 다루겠다! 나는 톰캣의 구조를 참고하여 HTTP 요청을 처리할 수 있는 WAS를 간단하게 구현해볼 생각이다. 나만의 WAS를 구현하기 전에, WAS의 기본적인 설정을 이해하기 위해 톰캣을 참고해보자.톰캣의 설정..
[Java] 소켓 통신과 네트워크 예외
·
Java
두 개의 호스트가 TCP/IP 프로토콜을 사용하여 서로 통신을 한다고 하자. 클라이언트와 서버 간의 데이터 통신을 위해서는 양쪽에 Socket이 열려있어야 한다. Socket은 서버와 연결되어 있는 연결점이라고 생각하면 된다. 자바에서는 다음과 같이 소켓을 통해 TCP 접속을 시도할 수 있다. 먼저 클라이언트에서 서버와 통신하기 위한 코드를 살펴보자.클라이언트 코드SocketSocket socket = new Socket("localhost", PORT);Socket 생성자의 매개변수로 호스트명과 포트번호를 전달한다.전달된 호스트명과 매핑되는 IP를 찾기 위해 Socket은 내부적으로 InetAddress를 사용한다InetAddress.getByName("호스트명")을 통해 호스트명과 매핑되는 IP 주소..
[Java] 제네릭(Generics)
·
Java
제네릭(Generics)이란제네릭(Generics): 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법컴파일 시 타입 안정성을 보장하고, 타입 캐스팅을 줄여 코드의 가독성과 재사용성을 높이기 위한 기능Java 5에서 처음 도입ex) List list = new ArrayList();위 코드에서 꺾쇠() 괄호가 제네릭. 이를 '다이아몬드 연산자'라고 함.=> List 클래스 자료형의 타입은 Integer 타입으로 지정되어 정수형 데이터만 리스트에 적재하 수 있게 됨제네릭은 배열의 타입을 지정하듯이 리스트 자료형 같은 컬렉션 클래스나 메소드에서 사용할 내부 데이터 타입(type)을 파라미터(parameter) 주듯이 외부에서 지정하는 이른바 타입을 변수화 한 기능제네릭 타입 매개변수다이아몬드 연산..
[Java] 스레드 풀 & ExecutorService
·
Java
스레드를 직접 사용할 때의 문제점스레드 생성 시간으로 인한 성능 문제메모리 할당: 스레드는 자신만의 호출 스택을 가지고 있어야 하는데, 이는 곧 메모리 공간을 할당해주는 작업이다.운영체제 자원 사용: 스레드 생성 작업은 시스템 콜(system call)을 통해 처리된다. 즉, CPU와 메모리 리소스를 소모하는 작업이다.운영체제 스케줄러 설정: 새로운 스레드가 생성되면 운영체제의 스케줄러는 이 스레드를 관리하고 실행 순서를 조정해야 한다 → 오버헤드참고로 스레드 하나는 보통 1MB 이상의 메모리를 사용한다.⇒ 스레드 생성 작업은 상대적으로 무거우며, 어떤 작업 하나를 수행할 때마다 스레드를 각각 생성하고 실행한다면, 이 생성 비용 때문에, 이미 많은 시간이 소모될 것⇒ 생성한 스레드를 재사용할 필요가 있다..
[Java] 동시성 컬렉션
·
Java
동시성 컬렉션이 필요한 이유java.util 패키지에 소속되어 있는 컬렉션 프레임워크들은 스레드 세이프(thread-safe)하지 않다!⇒ 원자적인 연산처럼 느껴지는 메서드들의 대부분은 내부를 확인해보면 모두 여러개의 연산들로 이루어져 있으며 이들은 동시성 문제를 유발할 수 있다..ArrayList에 값을 추가하는 경우만 해도, 내부에 있는 배열에 데이터를 추가하고, size도 증가시키는 것과 같은 작업을 해야하며, size를 증가시키기 위한 size++ 연산 자체도 원자적이지 않다.⇒ 멀티스레드 상황에서 여러 스레드가 동시에 컬렉션에 접근하는 경우라면 절대 java.util 패키지가 제공하는 일반적인 컬렉션들은 사용하면 안된다! (물론 일부 예외도 있다) 이렇게 원자적이지 않은 연산을 멀티스레드 상황에..
[Java] CAS - 동기화와 원자적 연산
·
Java
원자적 연산소개컴퓨터 과학에서 사용하는 원자적 연산(atomic operation)의 의미는 해당 연산이 더 이상 나눌 수 없는 단위로 수행된다는 것을 의미한다. 즉, 원자적 연산은 중단되지 않고, 다른 연산과 간섭 없이 완전히 실행되거나 전혀 실행되지 않는 성질을 가지고 있다. 쉽게 이야기해서 멀티스레드 상황에서 다른 스레드의 간섭 없이 안전하게 처리되는 연산이라는 뜻이다. 다음과 같은 필드가 있을 떄,volatile int i = 0; i = 1은 둘로 쪼갤 수 없는 원자적 연산이다. 단 하나의 순서로 실행되기 때문이다. 하지만, 다음의 연산은 원자적 연산이 아니다.i = i + 1; 왜냐하면 이 연산은 다음 순서로 나누어 실행되기 때문이다.오른쪽에있는 i의 값을 읽는다. i 의값은 10이다.읽은 ..