반응형

프로세스란 뭔가요? 🧐

프로세스의 개념은 프로그램과 관련 있습니다. 프로그램은 하드웨어에 '정적 상태'로 저장되어 있습니다. 누군가 실행시키지 않는 한 그 상태를 유지합니다. 그럼 프로그램이 실행되어 '동적 상태'로 되는 것은 무엇일까요? 이게 바로 프로세스입니다. 프로그램이 실행되어 메모리에 올라온 상태를 프로세스라고 합니다.

 

 

프로세스는 메모리에 올라간다!

프로그램이 실행되면 운영체제는 프로세스를 메모리의 적당한 위치로 가져오고, 프로세스의 정보들을 저장한 PCB(Process Control Block)를 생성합니다. 더 자세히는 프로세스는 메모리의 사용자(유저) 영역에, PCB는 커널 영역에 올라가게 됩니다. 

 

메모리

 

PCB(Process Control Block)
CPU가 프로세스를 실행하기 위해 필요한 프로세스 구분자, 메모리 관련 정보, 프로그램 카운터, 각종 중간값들을 보관하는 데이터 구조입니다. 프로그램이 프로세스가 되려면 메모리에 올라오는 것과 동시에 PCB가 반드시 생성되어야 합니다. 프로세스가 종료되면 프로세스는 메모리에서 삭제되며, PCB도 폐기됩니다. 

 

 

프로세스의 연산을 처리하는 CPU

실행중인 프로그램의 상태를 프로세스라고 했습니다. 그리고 실행중이라는 뜻은 프로그램에 정의된 코드들의 연산이 처리되는 것을 말합니다. 이 연산을 처리하는 것이 바로 CPU 입니다. 그럼 연산할 코드들은 어디서 얻어오는 걸까요? 바로 스레드입니다. 하나의 프로세스는 무조건 하나 이상의 스레드를 갖습니다. 이 스레드들을 CPU가 처리하는 것입니다.

 

프로세스 구조

프로세스에 스레드가 하나밖에 없으면 싱글 스레드, 둘 이상이면 멀티 스레드라고 말합니다. 이 둘의 구조적인 차이가 뭘까요? 이를 이해하기 위해서는 먼저 프로세스의 구조를 이해해야 합니다.

 

프로세스 구조

 

코드 영역

프로그램의 코드가 기술된 곳입니다. 프로그래머가 작성한 프로그램은 코드 영역에 탑재되며 탑재된 코드는 읽기전용으로 처리됩니다.

 

데이터 영역

코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳입니다. 데이터는 변하는 값이기때문에 읽기와 쓰기가 가능합니다. 물론 상수는 읽기 전용입니다.

 

스택 영역

운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳입니다. 프로세스 내에서 함수를 호출하면 함수 실행 후 돌아올 위치를 이 영역에 저장합니다. 위 예에서는 exit() 함수를 호출했을 때 돌아올 위치가 180이라는 주소임을 말하고 있습니다. 프로그램을 실행하면 운영체제는 프로그램을 메모리의 코드 영역에 넣습니다. 그리고 데이터 영역과 스택 영역을 확보하고  프로세스를 실행합니다. 이와 동시에 PCB도 생성합니다.

 

 

스레드가 뭔가요? 🤔

CPU가 처리하는 실행 단위를 말합니다. 한 개 이상의 스레드가 모여 프로세스를 이루기 때문에, 스레드를 프로세스 실행 단위라고도 합니다.

 

싱글 스레드와 멀티 스레드의 차이

이제 싱글 스레드와 멀티 스레드의 차이를 알아보겠습니다. 싱글 스레드는 앞서 언급한대로 프로세스가 하나의 스레드만을 갖는 것을 말합니다. CPU는 한번에 하나의 스레드만을 처리할 수 있으므로 CPU가 1 개인 시스템에서 프로세스의 실행은 문제가 되지 않습니다. 하지만 현재 시스템은 대부분 여러개의 CPU로 구성되어 있습니다. 필자의 경우 12개의 CPU 코어가 있으니, 동시에 12개의 스레드를 처리할 수 있습니다. 이러한 환경에서 단일 스레드 프로세스를 실행하게 되면 11개의 CPU 코어를 활용하지 못해 시스템의 효율성이 내려가게 됩니다. 이왕이면 여러 개의 스레드가 처리되는게 더 좋겠죠?

 

단일 스레드와 멀티 스레드를 대하는 CPU의 자세

 

 

프로세스를 여러개 만들면 되는거 아냐? 🤔

그럼 단일 스레드를 갖는 프로세스를 여러개 실행하면 어떻게될까요? 프로세스와 스레드가 새로 생성될것이고 여러 개의 CPU가 이들을 처리하게 될것입니다. 그런데 이 방식은 문제아닌 문제가 있습니다. 바로 프로세스마다 메모리 할당과 PCB 생성을 해야한다는 것입니다.

 

위에서 프로세스의 구조를 설명했는데 사실 힙 영역이라는 영역이 더 존재합니다. 그리고 힙 영역과 스택 영역은 동적 영역에 해당하는데 동적으로 크기가 줄어들고 늘어나는 영역입니다. 스택 영역은 함수 호출 후 복귀 시 사용하고, 추가로 지역변수를 저장할때 사용됩니다. 참고로 전역변수는 데이터 영역에 저장됩니다. 힙 영역은 프로그램이 실행되는 동안 할당되는 영역으로 자바의 인스턴스나 c언어의 malloc() 함수입니다.

 

프로세스 구조

 

 

스레드는 프로세스 구조 중 동적영역에 생성됩니다. 아래와 같이 말이죠. 

멀티 스레드

 

만약 단일 스레드 프로세스를 여러개 실행하면 어떻게될까요? 프로세스 개수만큼의 정적영역이 메모리에 추가로 할당되어야 할것입니다. 

멀티 태스킹

 

 

또 하나의 문제가 있습니다. 바로 Context Switching 속도가 느리다는 것입니다. 각각의 프로세스를 Context Switching 하는것보다 같은 프로세스를 갖는 스레드에 대해 Context Swtiching하는 속도가 더 빠릅니다.

 

Context Switching (문맥교환)
CPU를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 작업을 말합니다. 실행 상태에 있던 PCB에는 지금까지의 작업을 저장하고, 실행 상태로 들어오는 PCB의 내용으로 CPU가 다시 셋팅되는 작업입니다. 이와 같이 두 프로세스의 PCB를 교환하는 작업이 문맥교환입니다.

 

 

멀티 스레드의 문맥교환이 단일 스레드보다 더 빠른 이유가 뭐야? 🤔

멀티 스레드는 같은 프로세스에 속해있기 때문에 정적인 데이터를 공유하게 됩니다. 데이터 영역과 코드 영역을 공유합니다. 캐시는 CPU에서 읽어들인 메모리의 데이터를 저장하고 있다가 CPU가 다시 데이터를 요구할 때 메모리에서 전달해줍니다. 즉, 문맥 교환이 발생하고 PCB 내용을 기반으로 CPU를 셋팅할때 데이터 영역과 코드영역을 메모리영역에서 빠르게 읽어오게 됩니다. 왜? 프로세스가 같으니까요!

이에 반해 단일 스레드의 경우 PCB가 다르므로 기존에 쌓았던 캐시 데이터는 무의미해지고 CPU가 데이터를 읽어들이면 이를 다시 저장해야합니다. 이런 이유로 단일 스레드보다 멀티 스레드의 문맥교환이 더 빠른것입니다. 

 

 

그럼 문맥 교환은 언제 일어나는거야? 😲 

문맥 교환이 일어나는 상황은 매우 다양하나 대표적으로 두가지가 있습니다. 하나는 CPU가 처리중인 프로세스가 자신에게 주어진 시간을 다 사용했을 때이며, 하나는 인터럽트가 발생했을 때입니다. 인터럽트가 발생하는 상황은 매우 다양합니다. 예를들어 프로세스가 자신에게 주어진 메모리 공간을 넘어가려 한다면 인터럽트 관리 프로세스를 실행시킵니다. 이때 문맥교환이 발생합니다. 그리고 인터럽트 관리 프로세스가 메모리 범위를 넘어서려는 프로세스를 강제 종료하게 됩니다. 

 

멀티 스레드의 장점 

 

첫째, 응답성이 향상됩니다. 한 스레드가 입출력으로 인해 작업이 진행되지 않아도 다른 스레드가 작업을 계속하여 사용자의 작업 요구에 빨리 응답할 수 있습니다.

둘째, 자원을 공유합니다. 프로세스가 가진 자원을 모든 스레드가 공유하게 되어 작업을 원활하게 진행할 수 있습니다.

셋째, 시스템 효율성이 향상됩니다. 여러 개의 프로세스를 생성할 필요가 없어 불필요한 자원의 중복과 메모리 중복을 막고 문맥교환이 빨라집니다. 전반적인 시스템 효율이 향상되는 것입니다.

 

멀티 스레드의 단점

하나의 스레드에 문제가 생겨 종료될 경우 해당 스레드만 종료되는 것이 아니라 프로세스 전체가 종료됩니다. 인터넷 익스플로러는 멀티 스레드라 탭을 하나 추가할 경우 스레드가 생성된다. 이때 하나의 탭에 문제가 생겨 종료된다면 프로세스 자체가 종료되어 인터넷 익스플로러가 종료되게 됩니다. 이에반에 크롬은 싱글 스레드로 각 탭마다 독립적인 프로세스로 동작합니다. 만약 한 프로세스의 스레드에 문제가 생겨 종료되도, 다른 탭에 미치는 영향이 적습니다. 크롬은 이처럼 다른 스레드가 영향받는 것을 최소화하기 위해 낭비 요소가 있더라도 멀티스레드 대신 멀티태스킹을 사용합니다.

 

 

프로세스 상태

프로세스는 CPU 스케줄러에 의해 선별되며 스케줄러가 프로세스의 스레드를 CPU에게 전달하게 됩니다. 이를 '실행 상태' 라고 하는데, 이 외에도 여러 상태들이 있습니다. 한번 알아봅시다.

프로세스의 상태는 시스템마다 다르게 구성됩니다. 일괄 작업 시스템의 경우 생성, 실행, 완료 상태를 갖지만, 우리가 현재 대부분 사용하는 시분할 시스템의 프로세스 상태는 생성, 준비, 실행, 대기, 완료 상태를 갖습니다.

 

프로세스 상태

생성 상태

프로그램이 메모리에 올라오고, 운영체제로부터 PCB를 할당받은 상태입니다. 생성된 프로세스는 바로 실행되는 것이 아니라 준비 상태(준비 큐)에서 기다리게 됩니다.

 

준비 상태

프로세스가 CPU를 얻을때까지 기다리는 상태입니다. 준비 큐라는 곳에서 기다리며 CPU 스케줄러에 의해 관리됩니다.

참고로 CPU가 하나인 컴퓨터에서는 한번에 하나의 프로세스(정확히는 프로세스 내 스레드)만을 실행할 수 있습니다. CPU가 많을수록 준비 상태에 있는 프로세스가 빨리 처리될 것입니다.

 

CPU 스케줄러
준비 상태에 있는 여러 프로세스 중 다음 실행할 프로세스를 선정하는 일을 담당합니다. 준비 상태의 맨 앞에서 기다리는 PCB와 스레드를 CPU에게 전달하여 작업이 이루어지도록 합니다.

 

디스패치 (Dispatch)
준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 CPU 스케줄러의 작업을 말합니다.

 

 

실행 상태

준비 상태에 있는 프로세스 중 하나가 CPU를 얻어 실제 작업(스레드)을 수행하는 상태를 말합니다. 실행 상태에 들어가는 프로세스의 수는 CPU의 개수만큼입니다. 프로세스마다 할당된 시간(타임 슬라이스)을 다 사용하고도 작업이 끝나지 않는다면 해당 프로세스는 준비 상태로 돌아가 다음 차례를 기다리게 됩니다.

 

타임 슬라이스 (= 퀀텀)
프로세스에 할당된 작업 시간을 말합니다.

 

클록
타임 슬라이스가 지났는지를 CPU에게 알려주는 장치입니다. 시간이 끝나면 인터럽트를 발생시켜 CPU에게 알려줍니다.

 

 

대기 상태

프로세스가 실행 상태에서 입출력(I/O)을 요청할 경우 입출력이 완료될 때까지 기다리는 상태입니다. 이 상태의 프로세스는 입출력 장치별로 마련된 큐에서 기다립니다. 입출력이 완료되면 입출력 관리자로부터 인터럽트를 받고, 준비 상태로 이동하여 다음 작업 수행을 기다린다.

 

완료 상태

실행 상태의 프로세스가 주어진 시간 동안 작업을 마치거나 종료되는 상태입니다. 프로세스를 메모리에서 제거하고, PCB를 폐기합니다. 만약 비정상 종료될 경우 코어 덤프가 발생합니다.

 

코어 덤프
프로세스가 비정상 종료될 경우 강제 종료 직전 메모리 상태를 저장 장치로 옮기는 것

 

 

 

반응형

'CS' 카테고리의 다른 글

[CS] 웹 프락시 / Proxy  (0) 2023.09.20
[CS] HTTP 메시지  (0) 2023.08.30
[CS] URL이란?  (0) 2023.08.30
[CS] Web Cache / 웹 캐시란?  (0) 2023.08.23
반응형

1. 개요

  웹 프락시 서버는 중개자이다. 클라이언트와 서버 사이에 위치하여 그들 사이의 HTTP 메시지를 정리하는 중개인 역할을 한다.

 


2. 중개인 역할

 웹 프락시 서버는 클라이언트 입장에서 트랜잭션을 수행하는 중개인 역할이다. 클라이언트로부터 HTTP 요청을 받은 후 클라이언트 대신 실 서버와 통신하기 때문이다.

 


3. 개인 프락시와 공용 프락시

 

3.1. 공용 프락시

 공용 프락시는 여러 사용자에게 공유된 프락시로 일반적인 프록시 하면 공용 프록시라고 생각하면 된다. 캐시 서버나 보안에 활용된다.

 

3.2. 개인 프락시

 개인 프락시는 특정 사용자나 그룹이 특정 목적을 위해 사용하는 프락시를 말한다. VPN에 활용된다.

 


4. 프락시 vs 게이트웨이

 프락시는 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결하고, 게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상을 연결한다. 게이트웨이는 프로토콜 변환기의 역할까지 하는 것이다.

 하지만 실질적으로 프락시와 게이트웨이의 차이점은 모호하다. 브라우저와 서버는 다른 버전의 HTTP를 구현할 수 있기 때문에 때때로 약간의 프로토콜 변환을 할 수 있으며, 개인 프락시의 경우 SSL 보안 프로토콜을 지원하기 위해 게이트웨이의 기능을 구현하기 때문이다.

 


5. 프락시 사용 이유

 프락시 서버를 사용하면 보안 개선, 성능 향상, 비용 절약의 효과를 얻을 수 있다. 모든 HTTP 트래픽을 보고 요청을 핸들링할 수 있기 때문에 트래픽을 감시하고 수정할 수 있다.

 

 예를들어 성인 콘텐츠를 차단할 때 부적절한 사이트를 강제로 차단하거나, 서버의 리소스(ex 문서) 를 받아올 때 특정 클라이언트에게는 비밀번호를 요구하거나, 사본 리소스를 관리하여 리소스에 대한 접근 속도를 높여주는 웹 캐시 등으로 사용된다.

반응형
반응형

1. HTTP 메시지

 HTTP 메시지는 애플리케이션 간 주고받는 데이터의 블록들로 시작줄, 헤더, 본문으로 구성된다. 이 데이터 블록 안에 어떤 데이터들이 있는지 알아보고, 요청 메시지와 응답 메시지의 데이터가 약간 다르기때문에,이 차이도 알아보도록 하자.

 

HTTP 메시지 형태 (출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/Messages)

 

 


2. 시작줄

 요청 메시지의 시작줄에는 메서드, URL, HTTP 버전이, 응답 메시지의 시작줄에는 HTTP 버전, 상태 코드, 사유 구절 정보가 포함된다.


2.1. 메서드

 메서드는 서버에게 어떤 형식의 작업을 해야하는지 알려준다.

메서드 설명
GET 서버에서 데이터를 가져온다.
HEAD 서버에서 데이터에 대한 헤더만 가져온다.
POST 서버가 처리해야할 데이터를 보내거나, 새로 저장시킨다.
PUT 서버에 요청 메시지의 본문을 (덮어)저장한다.
PATCH 서버에 저장된 데이터의 일부분을 수정한다. (2010년 RFC 표준화됨)
TRACE 메시지가 프락시를 거쳐 서버에 도달하는 과정을 추적한다.
OPTIONS 어떤 메서드를 지원하는지 확인한다.
DELETE 서버에서 데이터를 제거한다.

 


2.2. POST와 PUT ??

사실 위는 책의 내용을 필자가 재해석하여 쓴것이다. 책에 기재된 POST와 PUT의 설명을 보고 바로 이해하기 어려웠기 때문인데, 책의 내용은 아래와 같다.

 

메서드 설명
POST 서버가 처리해야할 데이터를 보낸다.
PUT 서버에 요청 메시지의 본문을 저장한다.

 

 필자의 경우 POST는 데이터를 저장할때, PUT은 덮어쓸때 사용했었다. 그런데 POST 에는 없고 PUT에는 있는 '저장'이라는 단어가 잘 이해되지 않았다. HTTP 메서드에 대해 공식문서를 찾아본 결과 '멱등성'이라는 개념을 통해 이해하게 되었고, '저장'이라는 단어에 대해 편협하게 바라보고 있었다는 걸 깨닫게 되었다.

 

멱등성
 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 유지될 때 해당 HTTP 메서드가 멱등성을 가졌다고 말한다.

 

https://developer.mozilla.org/ko/docs/Glossary/Idempotent 

 

멱등성 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 다른 말로는, 멱등성 메

developer.mozilla.org

 모질라 개발자 페이지를 보면 HTTP 메서드 중 GET, HEAD, PUT, DELETE, OPTION, TRACE 는 멱등성 메서드, POST, PATCH는 비 멱등성 메서드라는 것을 알 수 있다.

 

 PUT 메서드는 Word나 한글파일에서의  '저장'과 같다고 생각했다. 처음 저장할때는 디스크에 새로 저장하지만, 이후부터는 계속 덮어쓴다. 동일한 내용을 한번 저장하는 것과 여러번 저장하는 것이 같은 효과를 지님과 동시에 서버의 상태도 동일하게 유지(리소스가 1개 -> 리소스가 1개)된다는 점에서 멱등성을 보장함을 알 수 있다.

 

  이에 반해 POST는 '다른이름으로 저장' 과 같다고 생각했다. 저장할때마다 무조건 디스크에 새로 저장하게 된다. 동일한 내용을 한번 '다른이름으로 저장'하는 것과 여러번 '다른이름으로 저장'하는 것이 같은 효과를 지니고 있지만, 리소스를 계속 생성하여 서버의 상태를 변경한다는 점에서 비멱등성이라는 것을 알 수 있다.

 

 이를 이해하니 PUT은 '서버에 요청 메시지의 본문을 저장한다'라는 내용도 이해할 수 있었다.

 


 

2.3. PATCH는 비멱등성?

 멱등성을 알아보던 중 한번의 물음표가 더 나왔다. PATCH는 특정 부분만 수정하니 당연히 멱등성 메서드일줄 알았으나 비멱등성 메서드라는 부분때문이었다. 결론은 PATCH는 로직에 따라 멱등성을 보장할 수 없기 때문에 비멱등성 메서드로 정의하고 있었다. 비멱등을 유발하는 케이스를 아래에 정리해보았다.

 

사용자의 나이를 한살 증가시키는 HTTP API가 있다고 가정하자. 이는 일부분을 변경하는 것이므로 PATCH 메서드를 사용할 것이며, 사용자의 나이에 1을 더하는 로직이 들어갈 것이다.

 만약 A라는 사용자의 나이가 5살이었다면, 한번 요청했을 때는 6살이, 두번 요청했을 때는 7살이 될 것이다. 이는 멱등성을 보장하지 않는다고 할 수 있다.

 반대로 만약 사용자의 이름을 변경하는 API가 있다고 가정하자. 마찬가지로 일부분을 변경하는 것이므로 PATCH 메서드를 사용할 것이며, 사용자의 이름을 요청 이름으로 변경하는 로직이 들어갈 것이다.
 만약 A라는 사용자의 이름을 B로 변경한다면, 한번 요청하던, 두번 요청하던 이름은 B가 될 것이다. 이는 멱등성을 보장한다고 할 수 있다.

 즉, 로직에 따라 멱등성을 보장할수도, 보장하지 못할수도 있으므로 비멱등성 메서드로 정의되는 것이다.

 


 

2.4. 상태코드

 상태코드는 서버에서 어떤 행위가 일어났는지에 대한 것을 코드로 표현한 것이다. 백단위마다 다른 종류로 분류된다.

전체 범위 분류
100 ~ 199 정보
200 ~ 299 성공
300 ~ 399 리다이렉션
400 ~ 499 클라이언트 에러
500 ~ 599 서버에러

 


2.5. 사유구절

 사유 구절은 상태 코드에 대한 설명을 말한다. 예를들어 200 상태 코드에 대해서는 OK이라는 사유구절이 포함된다.

 

2.6. HTTP 버전

 HTTP 애플리케이션들이 자신이 따르는 프로토콜의 버전을 상대방에게 말해주기 위한 수단으로 사용된다.

 


3. 헤더

 헤더는 HTTP의 요청과 응답 메시지에 더하는 추가 정보로, 이름/값 쌍의 목록으로 관리되며, 일반적으로 쿠키나 인증, 컨텐츠와 같은 메타 정보가 포함된다. 헤더는 목적에 따라 총 5가지로 분류된다.

 


3.1. 일반 헤더(General Header)

 클라이언트와 서버 양쪽 모두가 사용하는 헤더이다. 예를들어 Date 헤더는 서버와 클라이언트를 가리지 않고 메시지가 만들어진 일시를 지칭하기 위해 사용된다.

 


3.2. 요청 헤더(Request Header)

 요청 메시지를 위한 헤더이다. 예를 들어 "Accept : */*" 헤더는 서버에게 어떤 미디어 타입도 받을 수 있다는 것을 의미한다. 

 


3.3. 응답 헤더(Response Header)

 응답 메시지를 위한 헤더이다. 예를 들어 "Location : http://~" 헤더는 클라이언트에게 알려준 URL로 재 요청하라는 것을 의미한다.

 


3.4. 엔티티 헤더(Entity Header)

 본문에 대한 헤더를 말한다. 예를들어 Content-Type : text/html 헤더는 클라이언트에게 본문에 들어간 데이터가 HTML 문서라는 것을 의미한다.

 


3.5. 확장 헤더(Extension Header)

 개발자에 의해 커스텀되어 만들어졌지만 HTTP 명세에는 추가되지 않는 비표준 헤더이다.

 


4. 본문

 HTTP 메시지에 덱스트, 이미지, 비디오, HTML 문서 등 여러 종류의 디지털 데이터를 포함시켜 요청하기 위해 사용된다.

 


5. 출처

https://developer.mozilla.org/ko/docs/Web/HTTP/Messages - HTTP 메시지

https://developer.mozilla.org/ko/docs/Glossary/Idempotent - 멱등성

HTTP 완벽가이드 - 데이빗 고울리

 

반응형
반응형

1. URL이란?

 URL은 Uniform Resource Location의 약자로, 브라우저가 인터넷상의 정보를 찾는데 필요한 리소스(Resource) 위치(Location)를 말하며, 이 정보는 정형화(Uniform)되어 있다. 즉, 문법이 존재한다.

 


 

2. URL 문법

 URL은 일반적으로 9개 컴포넌트로 구성된다. 이 중 가장 중요한 컴포넌트 세가지는 스킴, 호스트, 경로이다.

<스킴>://<사용자 이름>:<비밀번호>@<호스트>:<포트>/<경로>;<파라미터>?<질의>#<프래그먼트>

 

컴포넌트 설명
스킴 리소스를 가져오기위해 사용할 프로토콜을 말한다. (ex. http, https)
사용자 이름 몇몇 스킴은 리소스에 접근하기 위해 사용자 이름을 필요로 한다.
비밀번호 사용자 이름에 대한 비밀번호를 가리킨다.
호스트 리소스를 호스팅하는 서버의 호스트 명이나 IP 주소이다.
포트 리소스를 호스팅하는 서버가 열어놓은 포트번호로 많은 스킴이 기본 포트를 갖는다. (ex. http는 80 포트)
경로 서버 내 리소스가 어디에 있는지를 가리킨다.
파라미터 입력 파라미터를 기술하는 용도로 사용된다. 매트릭스 파라미터 방식이 사용되나, JAX-RS라는 프레임워크만 지원되어 잘 사용되지 않는다.
질의 파라미터를 전달하는데 쓰인다. 이게 우리가 흔히 알고있는 쿼리 스트링이다.
프래그먼트 리소스의 특정부분을 가리키는 이름이며, 리소스 로드 후 특정 부분으로 스크롤을 이동시킨다. 서버에 전달되지 않으며 클라이언트에서만 사용한다. 

 


 

3. URL의 문자제한

 일반적으로 URL에는 ASCII 문자만 포함하도록 허락했다. 하지만 현대의 웹은 다양한 언어와 문자를 지원하기 위해 URL에 비-ASCII 문자도 사용할 수 있게 되었다. 인코딩 + 이스케이프 기능을 사용함으로써 말이다.

 예를들어 한글 '안'의 경우 ASCII 문자가 아니다. '안'을 UTF-8로 인코딩하면 'EC 95 88'이다. 이에 이스케이프 기능을 적용하면 % 기호로 시작하는 ASCII 문자열로 표현되며, 최종적으로 '%EC%95%88'로 변환된다.

 

반응형
반응형

웹 캐시란?

 브라우저가 웹 서버에 접속하여 받아온 정적 컨텐츠 (html, 이미지, js 등)를 메모리 또는 디스크에 저장해 놓는 것을 말한다. 이후 HTTP 요청을 할 경우 해당 리소스가 캐시에 있는지 확인하고 이를 재사용함으로써 응답시간과 네트워크 대역폭을 줄일 수 있다.


웹 캐시의 장점

1. 불필요한 네트워크 통신을 줄인다.

 클라이언트가 서버에게 문서를 요청할 때, 서버는 해당 문서를 클라이언트에게 전송하게 된다. 재차 똑같은 문서를 요청할 경우 똑같이 전송하게 된다.

 캐시를 이용하면, 첫번째 응답은 브라우저 캐시에 보관되고, 클라이언트가 똑같은 문서를 요청할 경우 캐시된 사본이 이에대한 응답으로 사용될 수 있기 때문에, 중복해서 트래픽을 주고받는 네트워크 통신을 줄일 수 있다.

 

2. 네트워크 병목을 줄여준다.

 많은 네트워크가 원격 서버보다 로컬 네트워크에 더 넓은 대역폭을 제공한다. WAN 보다 LAN이 구성이 더 쉽고, 거리도 가까우며, 비용도 적게들기 때문이다. 만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면, 캐싱 성능을 대폭 개선할 수 있다.

 

빠른 LAN을 통한 문서 조회

 

 예를들어 샌프란시스코 지사에 있는 사용자는 애틀랜타 본사로부터 문서를 받는데 30초가 걸릴 수 있다. 만약 이 문서가 샌프란시스코의 사무실에 캐시되어 있다면, 로컬 사용자는 같은 문서를 이더넷 접속, 즉 LAN을 통해 1초 미만으로 가져올 수 있을 것이다.

 

 

3. 거리로 인한 네트워크 지연을 줄여준다.

 대역폭이 문제가 되지 않더라도, 거리가 문제될 수 있다. 만약 보스턴과 샌프란시스코 사이에 네트워크 통신을 한다면 그 거리는 4,400 킬로미터이고, 신호의 속도를 빛의 속도(300,000 킬로미터 / 초)로 가정하면 편도는 약 15ms, 왕복은 30ms 가 걸린다.

 만약 웹페이지가 20개의 작은 이미지를 포함하고 있다면, 이 속도에 비례하여 통신 시간이 소요된다. 추가 커넥션에 의한 병렬처리가 이 속도를 줄일 수 있지만, 이보다 더 떨어진 거리거나, 훨씬 더 복잡한 웹페이지일 경우 거리로 인한 속도 지연은 무시할 수 없다.

 캐시는 이러한 거리를 수천 킬로미터에서 수십 미터로 줄일 수 있다.

 

4. 갑작스런 요청 쇄도(Flash Crowds)에 대처 가능하다.

 원 서버로의 요청을 줄이기때문에 갑작스런 요청 쇄도 (Flash Crowds) 에 대처할 수 있다.

 


적중과 부적중 (cache hit, cache miss)

 캐시에 요청이 도착했을 때, 그에 대응하는 사본이 있다면 이를 이용해 요청이 처리될 수 있다. 이를 캐시 적중(cache hit)라고 하고, 대응하는 사본이 없다면 원 서버로 요청이 전달된다. 이를 캐시 부적중(cache miss)라고 한다.


웹 캐시 체감하기

1. 기본 셋팅

 실제로 웹 캐시를 적용했을때와 그렇지 않았을 때의 차이를 비교해보자. 테스트 환경으로는 웹서버인 Apache 2.4 버전을 사용했으며, 보다 확실하게 체감하기 위해 Network 속도를 Slow 3G로 설정하였다. 이는 크롬 개발자 도구에서 설정 가능하다.

 

Network 속도 설정

 

 

 

1. 웹 캐시로부터 읽어오지 않은 응답

 

1) 최초 HTTP 통신

 최초 웹서버 접속 시 HTML 형태의 응답을 받고, HTML 내에 존재하는 정적 리소스를 로딩하기 위해 서버로 요청하고 있다.  이때 해당 리소스의 Size는 5~20 kb, Time은 약 2초 정도 걸렸다.

캐시를 적용하지 않았을 때의 첫번째 HTTP 통신

 

2) 두번째 HTTP 통신

 이후 동일 URI로 재요청 한다. 마찬가지로 HTML 형태의 응답을 받고, HTML 내에 존재하는 정적 리소스를 로딩하기 위해 다시 서버로 요청하고 있다. Size와 Time 모두 이 전 요청과 동일하다. 이를 통해 정적데이터가 필요할 때마다 서버로 요청한다는 것을 알 수 있다.

캐시를 적용하지 않았을 때의 두번째 HTTP 통신

 

 

2. 웹 캐시로부터 읽어온 응답

 

1) 최초 HTTP 통신

 최초 웹서버 접속 시 HTML 형태의 응답을 받고, HTML 내에 존재하는 정적 리소스를 읽어오기 위해 서버로 요청하고 있다. 이때 해당 리소스의 Size는 5~20 kb, Time은 약 2초 정도 걸렸다.

캐시를 적용했을 때의 첫번째 HTTP 통신

2) 두번째 HTTP 통신

 이후 동일 URI로 재요청 한다. 마찬가지로 HTML 형태의 응답을 받고, HTML 내에 존재하는 정적 리소스를 읽고 있다. 그런데 다른점이 있다. Size에 memory cache 가 적혀있고, Time은 0ms이다. 해당 리소스를 서버가 아닌 memory에서 조회했다는 것을 알 수 있다. 이를 통해 정적데이터가 캐시에 저장되어 있을 경우 캐시에서 로드한다는 것을 알 수 있다.

 


캐시 옵션 설정하기

 캐시는 Cache-Control이라는 HTTP Header로 설정할 수 있다. 먼저 해당 옵션을 살펴보자.

 

1. Cache-Control

설정 값 내용
no-store 캐시에 리소스를 저장하지 않는다.
no-cache 캐시 만료기간에 상관하지 않고 항상 원 서버에게 리소스의 재검사를 요청한다.
must-revalidate 캐시 만료기간이 지났을 경우에만 원 서버에게 리소스의 재검사 요청한다.
public 해당 리소스를 캐시 서버에 저장한다.
private 해당 리소스를 캐시 서버에 저장하지 않는다. 개인정보성 리소스이거나 보안이 필요한 리소스의 경우 이 옵션을 사용한다.
max-age 캐시의 만료기간(초단위)을 설정한다. 

 

※ 재검사가 뭔가요?

 재검사(Revalidation)는 신선도 검사라고도 하며, 캐시가 갖고 있는 사본이 최신 데이터인지를 서버를 통해 검사하는 작업을 말한다. 최신 데이터인 경우 304 Not Modifed 응답을 받게 되는데, 이는 '캐시에 있는 사본 데이터가 최신이며, 수정되지 않았다'라는 뜻을 의미한다. 이 경우 클라이언트는 해당 리소스를 캐시로부터 로드하게 된다. 

 

2. Apache httpd.conf 설정

 Apache 웹서버의 httpd.conf를 통해 설정할 수 있다. 필자의 경우 캐시의 만료기간을 10초로 설정하기 위해 아래 구문을 최하단에 넣어주었다. 서버를 재시작하여 설정을 적용하고 서버로 요청을 보내보자.

Header Set Cache-Control "max-age=10"

 

 만료기간 10초가 지나기 전에 다시 요청할 경우 캐시 메모리에 저장된 리소스를 가져옴을 확인할 수 있다. 

max-age=10 에 대한 테스트

 

  

3. HTTP Status 304

 캐시의 만료기간인 10초가 지나자 재검사를 진행했고, 서버의 리소스가 바뀌지 않아 304 상태코드를 리턴받고 있다. 그럼 재검증은 HTTP 메시지의 어떤 값을 통해 확인할 수 있는걸까?

200 > 304 StatusCode

 

 

요청 응답 데이터

 

 

 서버를 통해 리소스를 응답받으면 Response Header에 해당 리소스의 마지막 수정날짜가 들어간다. 아래 이미지를 보면 Last-Modified 헤더에 Sat, 04 May 2013 12:52:00 GMT로 되어있다.

HttpResponse - Last-Modified

 

 이를 우리나라 시간으로 환산하면 2013년 5월 4일 21시 52분인데, 실제 서버에 있는 리소스의 마지막 수정날짜이다.

apache_pb.gif 파일 정보

 

 

 이 후 서버로 리소스 요청을 보낼 때 요청 헤더의 If-Modified-Since 에 리소스의 마지막 수정날짜를 보낸다. 서버는 이 값과 실제 수정 날짜를 비교하여 일치하지 않을 경우, 즉 리소스가 변경된 경우에 200 코드와 함께 해당 리소스를 내려준다.

리소스가 변경되지 않았을 땐 304를, 리소스가 삭제되었다면 404를 응답한다.

 


캐시 포톨로지

 캐시는 한 명의 사용자에게만 할당될 수 있고, 수천 명의 사용자에게 공유될 수도 있다. 한명에게만 할당된 캐시를 전용 캐시, private cache라 하고, 여러 사용자가 공유하는 캐시는 공용 캐시, public cache 라고 한다.

 

 private cache의 대표적인 예는 방금 설명했던 브라우저 캐시이다. 웹 브라우저는 개인 전용 캐시를 내장하고 있으며 컴퓨터의 디스크 및 메모리에 캐시해놓고 사용한다.

Private cache

 

 public cache의 대표적인 예는 프락시 캐시라고 불리는 프락시 서버이다. 각각 다른 사용자들의 요청에 대해 공유된 사본을 제공할 수 있어 private cache보다 네트워크 트래픽을 줄일 수 있다.

 

Public cache

 


캐시 처리 단계

 웹 캐시의 기본적인 동작은 총 일곱 단계로 나뉘어져 있다.

 

캐시 처리 단계

1. 요청 받기

  먼저 캐시는 네트워크 커넥션에서의 활동을 감지하고, 들어오는 데이터를 읽어들인다. 즉, 서버로 요청하기 전 캐시에서 선 작업이 진행된다. (캐시는 HTTP의 응용계층에서 처리된다.)

 

2. 파싱

 캐시는 요청 메시지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료구조에 담는다. 이는 캐싱 소프트웨어가 헤더 필드를 처리하고 조작하기 쉽게 만들어준다.

 

3. 검색

 캐시는 URL을 알아내고 그에 해당하는 로컬 사본이 있는지 검사한다. 만약 문서를 로컬에서 가져올 수 없다면, 그것을 원 서버를 통해 가져오거나 실패를 반환한다.

 

4. 신선도 검사

 HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해준다. 이 기간동안 문서는 신선하다고 간주되고 캐시는 서버와의 접촉 없이 이 문서를 제공할 수 있다. 하지만 max-age를 넘을 정도로 너무 오래 갖고 있다면, 그 객체는 신선하지 않은 것으로 간주되며, 캐시는 그 문서를 제공하기 전 문서에 어떤 변경이 있었는지 검사하기 위해 서버와 통신하여 재검사 작업을 진행한다.

 

5. 응답 생성

 캐시는 캐시된 응답을 원 서버에서 온 것처럼 보이게 하고 싶기 때문에, 캐시된 서버 응답 헤더를 토대로 응답 헤더를 새로 생성한다.

 

6. 전송

 응답 헤더가 준비되면, 캐시는 응답을 클라이언트에게 돌려준다. 

 

7. 로깅

 대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지한다. 각 캐시 트랜잭션이 완료된 후, 캐지 적중과 부적중 횟수에 대한 통계를 갱신하고, 로그파일에 요청 종류, URL 그리고 무엇이 일어났는지를 알려주는 항목을 추가한다.

반응형

+ Recent posts